HashSet、LinkedHashSet、TreeSet

如果你需要一个访问快速的Set,你应该使用HashSet;当你需要一个排序的Set,你应该使用TreeSet;当你需要记录下插入时的顺序时,你应该使用LinedHashSet。

HashSet是采用hash表来实现的。其中的元素没有按顺序排列,add()、remove()以及contains()等方法都是复杂度为O(1)的方法。

TreeSet是采用树结构实现(红黑树算法)。元素是按顺序进行排列,但是add()、remove()以及contains()等方法都是复杂度为O(log (n))的方法。它还提供了一些方法来处理排序的set,如first(), last(), headSet(), tailSet()等等。

LinkedHashSet介于HashSet和TreeSet之间。它也是一个hash表,但是同时维护了一个双链表来记录插入的顺序。基本方法的复杂度为O(1)。

一、HashSet

1.不能保证元素的排列顺序,顺序有可能发生变化

2.不是同步的,非线程安全

3.集合元素可以是null,但只能放入一个null

4.当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。

5.简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等

6.Java中HashSet是用散列表实现的,散列表的大小默认为16,加载因子为0.75.

7.去重原理:当hashset add一个元素A的时候,首先获取这个元素的散列码(hashcode的方法),即获取元素的哈希值。

情况一:如果计算出的元素的存储位置目前没有任何元素存储,那么该元素可以直接存储在该位置上。

情况二:如果算出该元素的存储位置目前已经存在有其他元素了,那么会调用该元素的equals方法与该位置的元素再比较一次,如果equals返回的值是true,那么该元素与这个位置上的元素就视为重复元素,不允许添加,如果equals方法返回的是false,那么该元素运行添加。

二、LinkedHashSet

linkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

1.LinkedHashSet中不能有相同元素,可以有一个Null元素,元素严格按照放入的顺序排列。

2.LinkedHashSet如何保证有序和唯一性?

1).底层数据结构由哈希表和链表组成。

2).链表保证了元素的有序即存储和取出一致,哈希表保证了元素的唯一性。

3.添加、删除操作时间复杂度都是O(1)。

4.非线程安全

三、TreeSet

TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。

TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0

自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。

自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法

TreeSet是中不能有相同元素,不可以有Null元素,根据元素的自然顺序进行排序。

 四.总结:
通过以上特点可以分析出,三者都保证了元素的唯一性,如果无排序要求可以选用HashSet;如果想取出元素的顺序和放入元素的顺序相同,那么可以选用LinkedHashSet。如果想插入、删除立即排序或者按照一定规则排序可以选用TreeSet。

posted on 2022-06-17 23:32  情陌人灬已不在  阅读(104)  评论(0编辑  收藏  举报

导航