HashSet,TreeSet和LinkedHashSet的区别
1. Set接口
- Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。
- Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会接受这两个对象。
2. HashSet
HashSet有以下特点:
- 不能保证元素的排列顺序,顺序有可能发生变化
- 不是同步的,集合元素可以是null
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode值来决定该对象在HashSet中存储位置。简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等。
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对象通过equals方法比较返回true时,其hashCode也应该相同。
3. LinkedHashSet
- LinkedHashSet与HashSet的不同之处在于,LinkedHashSet维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。
- LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置。
4. TreeSet
- TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。
- TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
- TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0
自然排序根据排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。
obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是负数,则表明obj1小于obj2。
如果我们将两个对象的equals方法总是返回true,则这两个对象的compareTo方法返回应该返回0。如果要定制排序,应该使用Comparator接口,实现int compare(To1,To2)方法
5. 性能分析
- HashSet用的哈希表,开一个大数组,用哈希值映射到下标上,会有冲突,只有装填因子小的时候性能才好;
- HashSet要留额外空间,占内存大,数据频繁插入的时候可能会不断触发Array Copy,但是读写性能一般很快;
- TreeSet底层用红黑树实现,读写性能差一些,但不存在Array Copy问题,并且不占用额外的不存储数据的空间;
- 一般来说空间换时间或者时间换空间。HashSet的查找代价为O(1),TreeSet为O(logn);
- TreeSet的设计本身不是为了空间时间的问题,而是为了有序。因此它的插入及查找操作的代价都大于HashSet;
HashSet性能要好于TreeSet(特别是最常用的添加、查询元素等操作),因为TreeSet需要额外的红黑树算法维护集合元素的次序。
- LinkedHashSet对于普通的插入,删除操作比HashSet要略微慢一点,这是由维护链表所带来的额外开销造成的,但由于有了链表,遍历LinkedHashSet会更快;
EnumSet是所有Set实现类中性能最好的,但它只能保存同一个枚举类的枚举值作为集合元素;
6. 线程安全
注意:Set的三个实现类HashSet、TreeSet和EnumSet都是线程不安全的。
如果有多个线程同事访问一个Set集合,并且有超过一个线程修改了该Set集合,则必须手动保证该Set集合的同步。
- 解决:通常通过Collections工具类的synchronizedSortedSet方法来“包装”该Set集合。
- 注意:此操作最好在创建时进行,以防止对Set集合的意外非同步访问。
- 示例:
SortedSet set = Collections.synchronizedSortedSet(new TreeSet());
Collections 工具类其他同步方法:
synchronizedCollection(Collection<T> c)
这个方法返回一个同步的(线程安全的)集合的指定集合的支持。synchronizedList(List<T>list)
这个方法返回由指定列表支持的同步(线程安全的)列表。synchronizedMap(Map<K,V> m)
这个方法返回一个同步的(线程安全)由指定映射支持。synchronizedSet(Set<T> s)
这个方法返回一个同步的(线程安全的)集由指定set支持。synchronizedSortedMap(SortedMap<K,V> m)
这个方法返回一个同步的(线程安全的)有序映射所指定的有序映射支持synchronizedSortedSet(SortedSet<T> s)
这个方法返回一个同步的(线程安全的)有序set由指定的有序set支持。synchronizedNavigableMap(NavigableMap<K,V> m)(JDK1.8)synchronizedNavigableSet(NavigableSet<T> s)(JDK1.8)
7. 快速失败
什么是集合迭代器快速失败行为?以ArrayList为例,在多线程并发情况下,如果有一个线程在修改ArrayList集合的结构(插入、移除...),而另一个线程正在用迭代器遍历读取集合中的元素,此时将抛出ConcurrentModificationException异常立即停止迭代遍历操作,而不需要等到遍历结束后再检查有没有出现问题;
- Collection类返回一个Iterator之后,其实会创建一个指向原来对象的单链索引表,当原来的对象数量发生变化的时候,这个单链索引表的内容不会同步改变,所以当索引指针往后移动的时候,找不到要找的对象,就会按照fail-fast原则(快速失败原则),Iterator马上跑出java.util.ConcurrentModificationException异常。换一个说法,也就是,在Iterator工作的时候,是不允许被迭代的对象改变的。
- 避免抛出这个异常的方法是:不使用Collection自身的remove()方法,而使用Iterator本身的方法remove()来删除对象,因为这样子可以删掉原对象,同时当前迭代对象的索引也得到同步。
HashSet,TreeSet和LinkedHashSet的区别的更多相关文章
- HashSet,TreeSet和LinkedHashSet的区别
Set接口Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说,只要两个对象用eq ...
- Set下面HashSet,TreeSet和LinkedHashSet的区别
Set接口Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说,只要两个对象用eq ...
- 【java提高】---HashSet 与TreeSet和LinkedHashSet的区别
HashSet 与TreeSet和LinkedHashSet的区别 今天项目开发,需要通过两个条件去查询数据库数据,同时只要满足一个条件就可以取出这个对象.所以通过取出的数据肯定会有重复,所以要去掉重 ...
- HashSet 与TreeSet和LinkedHashSet的区别
Set接口 Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false. Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就 ...
- HashSet,TreeSet和LinkedHashSet
Set接口 Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false. Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说,只要两个对象用 ...
- Leetcode: LFU Cache && Summary of various Sets: HashSet, TreeSet, LinkedHashSet
Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the f ...
- Java集合详解7:HashSet,TreeSet与LinkedHashSet
今天我们来探索一下HashSet,TreeSet与LinkedHashSet的基本原理与源码实现,由于这三个set都是基于之前文章的三个map进行实现的,所以推荐大家先看一下前面有关map的文章,结合 ...
- Set集合[HashSet,TreeSet,LinkedHashSet],Map集合[HashMap,HashTable,TreeMap]
------------ Set ------------------- 有序: 根据添加元素顺序判定, 如果输出的结果和添加元素顺序是一样 无序: 根据添加元素顺序判定,如果输出的结果和添加元素的顺 ...
- Java集合详解7:一文搞清楚HashSet,TreeSet与LinkedHashSet的异同
<Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...
随机推荐
- html 模版
使用后台开发语言的都很了解语言的动态性给开发带来的好处,PHP,aspx,jsp页面都可以直接使用相应的语法和变量,输出的事就交给解释器或编译器了,用起来方便快捷,但需要额外的解释工作: 例如php模 ...
- Android-ViewPagerIndicator框架使用——使用概要
概要:关于ViewPagerIndicator这个框架,我这里只讲解如何使用,而不去讲解他是如何实现的,所以想了解源码剖析的朋友,这个就可以略过了. ViewPagerIndicator这个框架通过自 ...
- LeetCode具体分析 :: Recover Binary Search Tree [Tree]
Recover the tree without changing its structure. Note: A solution using O(n) space is pretty straigh ...
- No image!使用border-color属性来制作小三角形
border属性在项目中使用的还是蛮频繁的.例如页签.按钮这样的. border简写属性是按照如下属性设置的: border:border-width/border-style/border-colo ...
- JavaScript中的对象类型详解
To be finished 摘要 1.什么是对象? 2.引用类型和原始类型 3.对象数据属性拥有的特性(Attributes) 4.如何创建对象 a.直接定义 var mango={color:&q ...
- 【转】Gacutil.exe(全局程序集缓存工具)
全局程序集缓存工具使您可以查看和操作全局程序集缓存和下载缓存的内容. 安装 Visual Studio 和 Windows SDK 时会自动安装此工具. 要运行工具,我们建议您使用 Visual St ...
- <2013 08 26> 雅思听力相关
近两日开始接触雅思题型,初步做了6套剑桥雅思题的听力部分,完成情况还可以,这里做个总结. 1.听力总共约40左右道题目,30min左右完成,结束后有十分钟把答案写到答题卷上.所有听力材料都只播放一遍! ...
- NOIP2010~2017部分真题总结
NOIP2010~2017部分真题总结 2010 (吐槽)md这个时候的联赛还只有4题吗? 引水入城 只要发现对于有合法解的地图,每个蓄水厂贡献一段区间这个结论就很好做了 那么\(O(n^3)\)对每 ...
- shell一则-按文件每行长度排序
按文件每行长度排序 awk -F: '{print length($0) " " $0}' /etc/shadow | sort -r -n | awk '{print $2} ...
- PAT 1069. 微博转发抽奖(20)
小明PAT考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔N个人就发出一个红包.请你编写程序帮助他确定中奖名单. 输入格式: 输入第一行给出三个正整数M(<= 1000).N ...