黑马程序员--Java基础学习笔记【集合-Set】

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

Set 接口特点:

不允许存储重复元素,无序集合:存储取出没有顺序(不保证迭代顺序),没有索引

Set接口方法,和父接口Collection抽象方法完全一样

Set接口存储对象并迭代,找实现类HashSet集合

  • HashSet 如何保证元素唯一?

Set里的元素是不能重复的,使用 equals() 方法和 hashCode() 方法来区分重复与否。覆盖 equals() 方法、hashCode() 方法用来判断两个对象是否为同一对象,而“==”判断地址是否相等,用来决定引用值是否指向同一对象。

底层数据结构是哈希表,哈希表依赖于哈希值存储,添加功能底层依赖于两个方法 inthashCode(), boolean equals(Object obj) ,当存储对象时,先调用对象的 hashCode() 方法,校验哈希值是否与哈希表中已存在对象的哈希值相等,如果相等,当前对象调用 equals() 方法与表中已存在对象进行比较,如果结果是 true ,则哈希值一样,且比较结果为 true ,集合判断为同一对象不再存储。

如果两个对象,哈希值一样,equals一定返回 true 吗?不一定

如果两个对象,equals方法返回 true,拥有相同的哈希值吗?一定

HashSet特性:无序,不重复,无索引

底层数据结构是哈希表:数组 + 链表实现(元素是链表的数组)

存取速度都非常快,线程不安全集合,运行速度快

  • HashMap 和 HashSet 有什么关系?

HashSet 底层是采用 HashMap 实现的。

privatetransient HashMap<E, object> map;

HashSet 类里面定义的一个私有成员变量。放进 HashSet 中的对象,其实是用这个HashMap 的 key 来存储的。当调用 HashSet 的 add 方法时,实际上是向 HashMap 中增加了一行 (key-value) 对,该行的 key 就是向 HashSet 增加的那个对象,该行的 value 就是一个 Object 类型的常量(静态的 Object 对象)。

LinkedHashSet特点:元素有序(由链表保证)唯一(由哈希表保证)

since JDK1.4 ,出现时间晚于 Set 接口和父类 HashSet

继承 HashSet

存储和取出的顺序是一致的

底层结构是基于哈希表的链表实现

线程不安全集合

Set 接口是无序的集合,而LinkedHashSet 变成有序集合。

TreeSet 集合的自身特性:

底层数据结构是红黑树(自平衡的二叉树),保证元素的排序和唯一性

线程不安全,运行速度快

对存储的对象进行排序:

自然顺序排序

(java.lang.Comparable,对实现类的对象进行强制排序)

自定义的对象的类 implementsComparable<> ,

重写接口中的 compareTo() 方法,建立自定义对象的自然顺序

根据创建集合时传递的比较器进行排序

自定义比较器 implements Comparator<> ,

重写接口中的 compare() 方法

TreeSet存储自定义对象

TreeSet集合存储对象时,不考虑hashCodeequals

  1. 1.  TreeSet集合依据对象的自然顺序进行排序

要求存储到TreeSet集合中的对象,具有自然顺序

类实现Comparable接口,重写compareTo

2.TreeSet集合自己具备比较性

自定义比较器对象,实现java.util.Comparator,重写compare

接口实现类对象,传递给TreeSet集合

一旦有了比较器,TreeSet集合不考虑对象自然顺序

  • HashSet 集合存储自定义对象并遍历(如果对象的成员变量值相同即为同一个对象)

package cn.itcast.set;

importjava.util.HashSet;

import java.util.Set;

/*

* HashSet存储自定义对象,不存储相同的元素

* 校验对象的唯一性

* 依赖于在自定义对象中重写hashCode 和 equals 两个方法实现

*/

public classHashSetDemo {

public static void main(String[] args) {

Set<Person> set = new HashSet<>();

set.add(new Person("zs", 20));

set.add(new Person("ls", 21));

set.add(new Person("zs", 20));

for (Person person : set) {

System.out.println(person);

}

//     Person [name=ls, age=21]

//     Person [name=zs, age=20]

}

}

  • TreeSet 集合存储自定义对象并遍历

(如果对象的成员变量值相同即为同一个对象,按照年龄进行从大到小进行排序)

package cn.itcast.set;

import java.util.TreeSet;

publicclassTreeSetDemo {

publicstaticvoid main(String[] args) {

TreeSet<String>set= newTreeSet<String>();

set.add("www");

set.add("itcast");

set.add("cn");

for (String string : set) {

System.out.print(string + " ");

}

// cn itcast www 对存储的对象进行排序

System.out.println();

// 自然顺序比较

TreeSet<Person>set2= newTreeSet<Person>();

// 比较器比较

//     TreeSet<Person>set2 = new TreeSet<Person>(new PersonComparator());

set2.add(new Person("zs", 20));

set2.add(new Person("ls", 21));

System.out.println(set2);

// [Person [name=ls, age=21], Person [name=zs, age=20]]

}

}

/*

* 重写接口compareTo方法,建立Person类自然顺序

*

* @seejava.lang.Comparable#compareTo(java.lang.Object)

*/

@Override

publicint compareTo(Person o) {

intvalue = this.name.compareTo(o.name);

if (value == 0) {

returnthis.age - o.age;

}

returnvalue;

}

package cn.itcast.set;

import java.util.Comparator;

publicclassPersonComparator implements Comparator<Person>{

/*

* (non-Javadoc)

* @seejava.util.Comparator#compare(java.lang.Object, java.lang.Object)

*/

@Override

publicint compare(Person o1, Person o2) {

intvalue = o1.getAge() - o2.getAge();

if (value == 0) {

returno1.getName().compareTo(o2.getName());

}

returnvalue;

}

}

  • 键盘录入 5 个学生信息,按照总分从高到低输出到控制台

package cn.itcast.set;

importjava.util.Scanner;

import java.util.Set;

importjava.util.TreeSet;

public class SetTest1 {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

Set<StudentInfo> set = new TreeSet<StudentInfo>(new StudentScoreComparator());

for (int i = 0; i < 3; i++) {

String line = sc.nextLine();

String[] str = line.split(" +");

StudentInfo s = new StudentInfo(str[0],Integer.parseInt(str[1]), Integer.parseInt(str[2]),

Integer.parseInt(str[3]));

set.add(s);

}

for (StudentInfo studentInfo : set) {

System.out.println(studentInfo);

}

}

}

package cn.itcast.set;

import java.util.Comparator;

publicclassStudentScoreComparator implements Comparator<StudentInfo> {

@Override

publicint compare(StudentInfo o1, StudentInfo o2) {

intvalue = o1.getTotal() - o2.getTotal();

returnvalue == 0 ? o1.getName().compareTo(o2.getName()) : value;

}

}

时间: 2024-10-11 05:54:03

黑马程序员--Java基础学习笔记【集合-Set】的相关文章

黑马程序员--java基础学习笔记5

黑马程序员--java基础学习笔记6 一.笔记内容概述: 数组-第二种定义格式.数组-常见操作-遍历-最值-选择排序-冒泡排序-排序位置置换代码提取.数组-排序的性能问题.数组-常见功能-查找-折半查找.进制转换-查表法-整合. 二.常用内容介绍: 1.数组初始化的三种方式: int[] arr = new int[3]; int[] arr = new int[]{1,2,3}; int[] arr = {1,2,3}; 2.查表法: 如果数据中出现了对应关系,而且对应关系的一方是有序的数字编

黑马程序员--Java基础学习笔记【集合-Map】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- Map 接口 Map 接口定义的集合,又称查找表 Map 接口和 Collection 接口没关系 Map 集合派系,存储映射键值对 不允许重复的键,每个键最多映射 1 个值 根据内部数据结构不同,Map 接口有多种实现类: 常用的有内部为 hash 表实现的 HashMap 和内部为排序二叉树实现的 TreeMap Map 接口和 Collection 接口的不同 Map 和 Collect

黑马程序员--Java基础学习笔记【单例设计模式、网络编程、反射】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 设计模式分类: 创建模式:是对类的实例化过程的抽象化,又分为类创建模式和对象创建模式 类创建模式:工厂方法模式 对象-:简单工厂(静态工厂方法)模式.抽象工厂模式.单例模式.建造模式- 结构模式:描述如何将类或者对象结合在一起形成更大的结构 适配器模式.缺省模式.合成模式.装饰模式(包装模式).门面模式- 行为模式:对不同的对象之间划分责任和算法的抽象化 不变模式.策略模式.迭代子模式.命令模

黑马程序员--Java基础学习笔记【序列化、多线程】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 序列化流与反序列化流 ObjectOutputStream 对象输出流 writeObject(Object obj) 可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中 ObjectInputStream对象输入流 readObject(Objectobj) 从源输入流中读取字节序列,反序列化为一个对象并返回 序列化:将数据分解成字节流,以便存储在文件中或在网络上传输

黑马程序员--Java基础学习笔记【正则表达式、常用API】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 正则表达式 正则表达式的组成规则 java.util.regex.Pattern 常见组成规则 字符集合 [abc] a.b.c中任意一个字符 [^abc] 除了a.b.c的任意字符 [a-z] a-z中的任意一个字符 [a-zA-Z0-9] a-z.A-Z.0-9中任意一个字符 [a-z&&[^bc]] a-z中除了b和c以外的任意一个字符 预定义字符集 .任意一个字符 \d 任意一个

黑马程序员--java基础学习笔记8

 一.笔记内容概述: 面向对象(数组工具对象建立-文档注释-单例设计模式&内存图解).继承.单继承和多重继承. 二.常用内容介绍: 1.继承的好处:提高了代码的复用性;让类与类之间产生了关系;开发最终的核心内容:不断地创建对象,使用对象,并维护着对象之间的关系. 2.什么时候使用继承? 当类与类之间存在着所属关系的时候,就定义继承;java不直接支持多继承,因为多个父类中如果有相同成员时,就会出现调用的不确定性;java中通过多实现implements的方式来间接体现多继承; 3.如何学习一

黑马程序员--Java基础学习笔记【异常处理】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 异常 异常就是Java程序在运行过程中出现的导致程序无法正常运行的错误. Java 中异常继承体系,顶层的类 java.lang.Throwable java.lang.Exception 所有异常的超类 RuntimeException 运行时异常可以不处理 非RuntimeExceptioin非运行时异常必须捕获处理 java.lang.Error 所有错误的超类 异常处理机制 当程序中抛

黑马程序员--java基础学习笔记6

一.笔记内容概述: 面向对象(概述&举例).类与对象的之间的关系.类与对象体现&细节.对象的内存体现.成员变量和局部变量的区别.类类型参数.匿名对象.基本数据类型参数传递图解.引用数据类型参数传递图解.封装&代码示例.面向对象(封装&思想).二维数组&定义方式&内存图解&另一种定义方式&应用场景. 二.常用内容介绍: 1.面向对象的特征: a.封装:将具体动作封装起来,方便调用,提高了代码的复用性和安全性. b.继承:继承某个类后,可以直接调

黑马程序员--Java基础学习笔记【IO流-字节流、转换流】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- IO 流 常用基类 字节流 InputStreamOutputStream 常用方法 int read() // 读取一个字节,以 int 形式返回 intread(byte[] b) // 读取最多数组长度个字节并存入该数组,返回实际读取字节 void write(int d) // 写出一个字节 voidwrite(byte[] d) // 将给定字节数组中的所有字节全部写出 void w