java的Set集合

 

HashSet:

/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* the specified initial capacity and default load factor (0.75).
*
* @param      initialCapacity   the initial capacity of the hash table
* @throws     IllegalArgumentException if the initial capacity is less
*             than zero
*/
public HashSet(int initialCapacity) {
    map = new HashMap<>(initialCapacity);
}
HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。底层数据结构其实是HashMap,固定value,将数据存入key中,利用HashMap的key不可重复的特点实现该集合特性。
特点:
  • 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也可能发生变化;
  • HashSet不是同步的;
  • 集合元素值可以是null;
内部存储机制:
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。如果有两个元素通过equals方法比较true,但它们的hashCode方法返回的值不相等,HashSet将会把它们存储在不同位置,依然可以添加成功。
也就是说。HashSet集合判断两个元素的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode方法返回值也相等。
靠元素重写hashCode方法和equals方法来判断两个元素是否相等,如果相等则不添加,依此来确保元素的唯一性
由于其是使用hashmap中的key实现的,所以其逻辑就是hashmap的key定位逻辑,数组加链表形式,一定长度后,链表转成二叉树。
hash表:
容量:hash表中桶的数量;
初始化容量:创建hash表时桶的数量;
尺寸:当前hash表中记录的数量;
负载因子:负载因子等于0表示空的hash表,0.5表示半满的hash表,轻负载的hash表具有冲突少、适宜插入与查询等特点。
负载极限:负载极限是一个0~1之间的数值,决定了hash表的最大填满程度。当hash表的负载因子达到指定负载极限时,hash表会自动成倍地增加容量,并将原有的对象重新分配,放入新的桶中。HashSet、HashMap、Hashtable默认的负载极限是0.75。

LinkedHashSet:

/**
* Constructs a new, empty linked hash set.  (This package private
* constructor is only used by LinkedHashSet.) The backing
* HashMap instance is a LinkedHashMap with the specified initial
* capacity and the specified load factor.
*
* @param      initialCapacity   the initial capacity of the hash map
* @param      loadFactor        the load factor of the hash map
* @param      dummy             ignored (distinguishes this
*             constructor from other int, float constructor.)
* @throws     IllegalArgumentException if the initial capacity is less
*             than zero, or if the load factor is nonpositive
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

LinkedHashSet继承于HashSet,但是由于在HashSet的初始化代码处做了处理,如果是HashSet,则内部的数据是HashMap实现,如果是LinkedHashSet,则内部数据使用的是LinkedHashMap,LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,即数组加双向链表的组合,这样就能从头节点按插入顺序迭代整个数据链。这样使得元素看起来是以插入的顺序保存的,也就是说当遍历集合LinkedHashSet集合里的元素时,集合将会按元素的添加顺序来访问集合里的元素。输出集合里的元素时,元素顺序总是与添加顺序一致。但是LinkedHashSet依然是HashSet,因此它不允许集合重复。

TreeSet:

TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态(不是添加顺序,而是根据数据进行排序)。
内部存储机制
TreeSet内部实现的是 红黑树,默认整形排序为从小到大。
TreeSet支持两种排序方法:自然排序和定制排序,在默认情况下,采用的是自然排序。
自然排序:TreeSet会调用集合元素的compareTo(Objec obj)方法来比较元素之间的大小关系,然后将集合元素按升序排列,这就是自然排序。
定制排序:Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现该接口的类必须实现该方法,实现了该接口的类必须实现该方法,实现接口的类就可以比较大小了。当调用一个一个对象调用该方法与另一个对象进行比较时,如果返回0表示两个对象相等;如果返回正整数则表明obj1大于obj2,如果是负整数则相反。

CopyOnWriteArraySet:

线程安全,底层使用的是CopyOnWriteArrayList,使用其特性实现的线程安全效果和不重复的效果,CopyOnWriteArrayList本身就有一个如果不存在才允许添加的api可以使用 addIfAbsent。

ConcurrentSkipListSet:

线程安全,其内部使用ConcurrentSkipListMap作为数据的存储,依旧使用其key。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值