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面试指南>仓库,更多精彩内容请到我的仓库里查 ...
随机推荐
- TelephonyManager&GsmCellLocation类的方法详解
转载:http://blog.163.com/zhangzheming_282/blog/static/117920962011101944356511/ TelephonyManager类 主要提供 ...
- python 推荐算法
每个人都会有这样的经历:当你在电商网站购物时,你会看到天猫给你弹出的“和你买了同样物品的人还买了XXX”的信息:当你在SNS社交网站闲逛时,也会看到弹出的“你可能认识XXX“的信息:你在微博添加关注人 ...
- 简单的c语言小程序 回光返照
主函数 int main(int argc,char * argv[]) -- arg代表英文的参数缩写 c代表count计数 argc { return 0; -- 0返还给系统,代表程序正确运行 ...
- PHP中如何配置smarty框架实现PHP代码和HTML代码分离
header('Cache-Control:Private');//保留用户填写的信息 session_start();//开启缓存 define('MYCMS','UTF-8');//定义网站编码常 ...
- 【BZOJ4066】简单题 KDtree
[BZOJ4066]简单题 Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: 命令 参数限制 内容 1 x y A 1<=x,y& ...
- 【BZOJ1941】[Sdoi2010]Hide and Seek KDtree
[BZOJ1941][Sdoi2010]Hide and Seek Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了 ...
- Fennec VS. Snuke
Fennec VS. Snuke Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statement Fenne ...
- 什么是 C++ 11 原始字符串?
std::string path = "C:\\VulkanSDK";//需要转义 std::string path = R"(C:\VulkanSDK)";/ ...
- 使用QFile进行文件操作(QFile可以使用FILE *指针,还必须指定AutoCloseHandle)
QFile类我我们提供了操作文件的常用功能.它是一种io设备,可以用来读写文本文件和二进制文件,也可以用来读写Qt的资源文件.QFile类可以单独使用,该类本身提供了read/write函数,但更方便 ...
- CentOS 7.4 下安装Epel源和Nginx
EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项目,为“红帽系”的操作系统提供额外的软件包,适用于RHEL.CentOS和Scientif ...