集合之Set集合
set集合特点
- 无序:存取顺序不一致
- 不重复:可以去除重复
- 无索引:不能使用普通for循环进行遍历,也不能通过索引来获取元素
Set集合实现类特点
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:排序、不重复、无索引
- Set集合自定义的方法较少,主要是实现了Collection接口的方法。但是不能使用普通for循环进行遍历,因为Set集合没有索引。
HashSet
Set<String> sets = new HashSet<>();
sets.add("java");
sets.add("java");
sets.add("Vue");
sets.add("go");
sets.add("Spring boot");
sets.add("mysql");
/*
* 虽然添加了两个java字符串,并且mysql在最后进行添加。
* 但是输出的结果是一个java,并且mysql字符串出现在了中间
* 这就体现了HashSet集合的特点:无序、不重复、无索引(没有get()方法)
* */
System.out.println(sets); //输出为 [java, Vue, go, mysql, Spring boot]
- HashSet集合底层采取哈希表存储数据,而哈希表是一种对于增删改查性能都比较好的结构
- JDK8以后,底层采用数组+链表+红黑树的方式实现哈希表

哈希值
哈希值是JDK根据对象的地址,按照某种规则算出来的int类型的数值,在java中通过 public int hashCode()方法返回对象的哈希值。同一个对象多次调用hashCode()方法返回的哈希值是相同的,默认情况下,不同对象的哈希值是不同的。
Java中哈希表的实现流程
- 创建一个默认长度为16,加载因子为0.75的数组,数组名为table
- 根据元素的哈希值跟数组的长度求余计算出应存入的位置
- 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素,则调用equals方法比较属性值。如果一样则不存入,如果不一样则存入。 (如果希望Set集合认为2个内容一样的对象是重复的,必须重写对象的hashCode()和equals()方法)
- 当数组存入到16*0.75=12,就自动扩容,每次扩容到原先的两倍
LinkedHashSet
特点:
- 有序、不重复、无索引
- 有序指的是保证存储和取出的元素顺序一致
- 底层数据结构依然是哈希表,但是每个元素又额外多了一个双链表的机制记录存储的顺序

TreeSet集合
- 不重复、无索引、可排序
- 按照元素的大小默认升序排序
- TreeSet底层是基于红黑树的数据结构实现排序,增删改查性能都比较好
TreeSet集合默认的规则
- 对于数值类型:Interger,Double,按照大小进行升序排序
- 对于字符串类型:按照默认首字符的编号升序排序
- 对于自定义类型排序,TreeSet无法直接排序,需要指定自定义排序规则
自定义排序规则有以下返回值规则,以及两种实现方法:
自定义排序规则中,两个值比较的返回值规则:
- 如果认为第一个元素大于第二个元素返回正整数
- 如果认为第一个元素小于第二个元素返回负整数
- 如果认为第一个元素等于第二个元素返回0,此时TreeSet集合只保留一个元素。
自定义排序规则的两种方法:
- 通过在类中实现Comparable接口,重写里面的compareTo方法来定制比较规则
- TreeSet集合有参构造器中,可以设置Comparator接口对应的比较器对象,来定制比较规则
/*
* 实现接口中的compareTo方法,在里面定制规则
* */
@Override
public int compareTo(Company o) {
return this.state-o.state;
}
/**
* 在创建TreeSet集合时,调用它的有参构造方法,实现Comparator接口。在接口里定制比较规则
*/
Set<Company> companies = new TreeSet<>(new Comparator<Company>() {
@Override
public int compare(Company o1, Company o2) {
return o1.getState()-o2.getState();
}
});
Collection集合的选择
- 希望元素可重复、有索引、查询快:ArrayList集合,基于数组
- 希望元素可重复、有索引、增删首尾快:LinkedList集合,基于双链表
- 希望元素增删改查都快,但是元素不重复、无索引、无序:HashSet集合,基于哈希表
- 希望元素增删改查都快,但是元素不重复、无索引、有序:LinkedHashSet集合,基于哈希表和双链表
- 希望对对象进行排序:TreeSet集合,基于红黑树
本文系作者 @Stone 原创发布在 zlprime。未经许可,禁止转载。