Set集合,继承自java.util.Collection接口,是java.util下的无序集合,允许null值
set集合特性
- 无序
- 不可重复
- 非线程安全
set实现类
1)HashSet : 底层哈希表,hashmap机制,不可重复,迭代无序输出
2)LinkedHashSet: 底层链表+哈希表,hashmap机制,不可重复,迭代按插入的顺序输出
3)TreeSet: 底层二叉树,hashmap机制,有序不可重复,迭代按hashcode顺序输出
Set是如何保证不可重复
Set底层是使用的HashMap机制
HashSet的add方法调用了HashMap的put方法,元素值作为map的key值,所以,不可重复
HashSet不可重复是因为封装类重写了hashcode和equlas方法
若像Set中放入相同的HashCode和equals相同,是否会覆盖
Set中放入相同的元素,不会覆盖;
Map中放入相同的key,不同的value值,key不会覆盖,value会修改
Set扩容机制
Set的底层是HashMap,Set构造器使用的HashMap的构造器,所以,Set的扩容机制同Map一样
1)初始化时容量为0,只是申请了内存
2)当set调用add方法添加第一个元素时,增至map的默认容量16
3)继续添加元素,到达Map容量的临界值*0.75时会触发扩容,容量扩容为原来的*2倍
4)临界值设为0.75:可以防止内存浪费,以及能及时扩容
LinkedHashSet是如何保证按插入顺序输出的
LinkedHashSet是HashSet的子类,底层是LinkedHashMap,数组+双向链表
hashcode决定了元素的位置,双向链表的结构保证了set可以按插入顺序顺序输出
TreeSet是如何保证内部排序的
TreeSet在添加元素时使用的是TreeMap,TreeMap添加元素的方法调用到了comparator方法
TreeSet两种排序
1)自然排序:指添加到set中的元素已经实现了comparable接口
class User implements Comparable<User>
重写compareTo方法
2)比较器排序:指在定义set时调用自定义的实现了comparator接口的比较器
class TestComparator implements Comparator<User>
Set set = new TreeSet(new TestComparator());
comparable接口和comparator接口的区别
- comparable接口在java.lang包下
java中的封装类等均已实现了comparable接口并冲给了compareTo方法
对于自定义的一些对象类,若添加到set中需要实现此comparable接口并重写compareTo方法
- comparator接口在java.util包下
对于set集合来说,可以写一个比较器类实现comparator接口,初始化set的时候调用比较器,可以保证set集合内元素按指定顺序存储
若set中元素既实现了comparable接口,同时,set也使用了比较器,会优先使用比较器排序