Set参考文章:
Java中的Set总结:https://www.jianshu.com/p/d6cff3517688
Java集合--Set(深入学习):https://www.jianshu.com/p/2d7b4847454b
Java集合详解7:HashSet,TreeSet与LinkedHashSet:https://blog.csdn.net/a724888/article/details/80295328
在判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现。
HashSet是哈希表结构,主要利用HashMap的key来存储元素,计算插入元素的hashCode来获取元素在集合中的位置;
TreeSet是红黑树结构,每一个元素都是树中的一个节点,插入的元素都会进行排序;
--| Set 如果是实现了Set接口的集合类,具备的特点: 无序,不可重复。
---| HashSet 底层是使用了哈希表来支持的,特点: 存取速度快.
该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。
---| TreeSet 该类实现了Set接口,可以实现排序等功能。
---| LinkHashSet 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。
Set
HashSet
HashSet在存储元素的过程中首先会去调用元素的hashCode()值,看其哈希值与已经存入HashSet的元素的哈希值是否相同,如果不同 :就直接添加到集合;如果相同 :则继续调用元素的equals() 和哈希值相同的这些元素依次去比较。如果说有返回true的,那就重复不添加;如果说比较结果都说false,那就是不重复就添加。为了减少equals的比较次数提高效率一般情况让属性不同的对象尽量hashCode()值不同,那么如何重写 equals()和hashCode()呢? Eclipse自动生成即可。
HashSet底层由HashMap实现,插入的元素被当做是HashMap的key,根据hashCode值来确定集合中的位置,由于Set集合中并没有角标的概念,所以并没有像List一样提供get()方法。当获取HashSet中某个元素时,只能通过遍历集合的方式进行equals()比较来实现;
具有如下特点:
-
不允许出现重复因素;
-
允许插入Null值;
-
元素无序(添加顺序和遍历顺序不一致);
-
线程不安全,若2个线程同时操作HashSet,必须通过代码实现同步;
不允许存储重复元素的原理
HashSet集合存储数据结构-哈希表
TreeSet
TreeSet:元素唯一,更重要的一个是给元素进行排序
TreeSet是红黑树结构,每一个元素都是树中的一个节点,插入的元素都会进行排序;
具有如下特点:
-
对插入的元素进行排序,是一个有序的集合(主要与HashSet的区别);
-
底层使用红黑树结构,而不是哈希表结构;
-
允许插入Null值;
-
不允许插入重复元素;
-
线程不安全;
通过查看源码发现,在TreeSet调用add方法时,会调用到底层TreeMap的put方法,在put方法中会调用到compare(key, key)方法,进行key大小的比较;
treeSet添加自定义元素:
treeSet要注意的事项:
1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该元素所属的类必须要实现Comparable接口,把元素的比较规则定义在compareTo(T o)方法上。
还有另一种方式,那就是实现Comparetor<t>接口,并重写compare方法;
3. 如果比较元素的时候,compareTo方法返回 的是0,那么该元素就被视为重复元素,不允许添加.(注意:TreeSet与HashCode、equals方法是没有任何关系。)
4. 往TreeSet添加元素的时候, 如果元素本身没有具备自然顺序 的特性,而元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个比较器。
5. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口, 在创建TreeSet对象的时候也传入了比较器,那么是以比较器的比较规则优先使用。
LinkedHashSet
HashSet
不保证顺序元素。 LinkedHashSet
在插入元素时保持元素顺序。
LinkedHashSet是HashSet的一个“扩展版本”,HashSet并不管什么顺序,不同的是LinkedHashSet会维护“插入顺序”。HashSet内部使用HashMap对象来存储它的元素,而LinkedHashSet内部使用LinkedHashMap对象来存储和处理它的元素。