HashSet vs TreeSet vs LinkedHashSet
使用Set集合的主要原因是因为Set集合里面没有重复的元素。Set集合有三个常见的实现类:HashSet,TreeSet,LinkedHashSet。什么时候,选择哪一个使用非常重要。简单的说,如果你关注性能,应该使用HashSet;如果你需要一个有序的Set集合,应该使用TreeSet;如果你需要一个Set集合保存了原始的元素插入顺序,应该使用LinkedHashSet。
Set接口
Set接口继承Collection接口。Set集合不允许里面存在重复元素,每个元素都必须是唯一的。你只需要往Set集合简单的添加元素,重复元素会被自动移除。
HashSet,TreeSet,LinkedHashSet对比
HashSet是基于散列表实现的,元素没有顺序;add、remove、contains方法的时间复杂度为O(1)。
TreeSet是基于树实现的(红黑树),元素是有序的;add、remove、contains方法的时间复杂度为O(log (n))。因为元素是有序的,它提供了若干个相关方法如first(), last(), headSet(), tailSet()等;
LinkedHashSet介于HashSet和TreeSet之间,是基于哈希表和链表实现的,支持元素的插入顺序;基本方法的时间复杂度为O(1);
TreeSet例子
TreeSet<Integer> tree = new TreeSet<Integer>(); tree.add(12); tree.add(63); tree.add(34); tree.add(45); Iterator<Integer> iterator = tree.iterator(); System.out.print("Tree set data: "); while (iterator.hasNext()) {System.out.print(iterator.next() + " "); }
结果输出:
Tree set data: 12 34 45 63
现在,我们换个元素类型,在进行插入,首先定义一个Dog类,如下
class Dog {int size;public Dog(int s) {size = s;}public String toString() {return size + "";} }
然后,往TreeSet添加若干个Dog对象,如下:
public class Q17 {public static void main(String[] args) {TreeSet<Dog> dset = new TreeSet<Dog>();dset.add(new Dog(2));dset.add(new Dog(1));dset.add(new Dog(3));Iterator<Dog> iterator = dset.iterator();while (iterator.hasNext()) {System.out.print(iterator.next() + " ");}}}
以上代码,编译OK,但是运行时报错,如下:
Exception in thread "main" java.lang.ClassCastException: simplejava.Dog cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1188)
at java.util.TreeMap.put(TreeMap.java:531)
at java.util.TreeSet.add(TreeSet.java:255)
at simplejava.Q17.main(Q17.java:22)
为什么呢?因为TreeSet是有序的,Dog类需要实现java.lang.Comparable接口的compareTo(),如下:
class Dog implements Comparable<Dog>{int size;public Dog(int s) {size = s;}public String toString() {return size + "";}@Overridepublic int compareTo(Dog o) {return size - o.size;} }
结果输出:
1 2 3
HashSet例子
HashSet<Dog> dset = new HashSet<Dog>();dset.add(new Dog(2));dset.add(new Dog(1));dset.add(new Dog(3));dset.add(new Dog(5));dset.add(new Dog(4));Iterator<Dog> iterator = dset.iterator();while (iterator.hasNext()) {System.out.print(iterator.next() + " ");}
结果输出:
5 3 2 1 4
注意顺序是不确定的。
LinkedHashSet例子
LinkedHashSet<Dog> dset = new LinkedHashSet<Dog>();dset.add(new Dog(2));dset.add(new Dog(1));dset.add(new Dog(3));dset.add(new Dog(5));dset.add(new Dog(4));Iterator<Dog> iterator = dset.iterator();while (iterator.hasNext()) {System.out.print(iterator.next() + " ");}
结果输出如下,保存了插入顺序:
2 1 3 5 4
性能测试
以下代码测试了这三个类add方法的性能:
Random r = new Random();HashSet<Dog> hashSet = new HashSet<Dog>();TreeSet<Dog> treeSet = new TreeSet<Dog>();LinkedHashSet<Dog> linkedSet = new LinkedHashSet<Dog>();// start timelong startTime = System.nanoTime();for (int i = 0; i < 1000; i++) {int x = r.nextInt(1000 - 10) + 10;hashSet.add(new Dog(x));}// end timelong endTime = System.nanoTime();long duration = endTime - startTime;System.out.println("HashSet: " + duration);// start timestartTime = System.nanoTime();for (int i = 0; i < 1000; i++) {int x = r.nextInt(1000 - 10) + 10;treeSet.add(new Dog(x));}// end timeendTime = System.nanoTime();duration = endTime - startTime;System.out.println("TreeSet: " + duration);// start timestartTime = System.nanoTime();for (int i = 0; i < 1000; i++) {int x = r.nextInt(1000 - 10) + 10;linkedSet.add(new Dog(x));}// end timeendTime = System.nanoTime();duration = endTime - startTime;System.out.println("LinkedHashSet: " + duration);
结果如下,我们可以发现,HashSet性能最好(注:以上代码我自己本地测试,HashSet不一定比LinkedHashSet快...)。
HashSet: 2244768
TreeSet: 3549314
LinkedHashSet: 2263320
这个测试并不是很精准,但是基本可以反映出TreeSet是性能最差的,因为需要排序。
相关阅读:ArrayList vs. LinkedList vs. Vector
译文链接:http://www.programcreek.com/2013/03/hashset-vs-treeset-vs-linkedhashset/
HashSet vs TreeSet vs LinkedHashSet相关推荐
- HashSet、TreeSet和LinkedHashSet
Set不能包含重复的元素.有三个通用的set接口的实现:HashSet.TreeSet和LinkedHashSet.什么时候用以及用哪个是一个重要的问题.总体来说,如果要一个快速的集合,就用HashS ...
- Java容器源码分析-HashSet vs TreeSet vs LinkedHashSet
2019独角兽企业重金招聘Python工程师标准>>> 这几天看了下容器的源码,总结一下HashSet vs TreeSet vs LinkedHashSet的区别, 如下图,col ...
- Set 、HashSet、TreeSet、LinkedHashSet、EnumSet
Set 底层原理: java中set及其子类都是由对应的Map实现的,如HashSet由HashMap实现,TreeSet由TreeMap实现等等. private static final Obje ...
- HashSet 与TreeSet和LinkedHashSet的区别
今天项目开发,需要通过两个条件去查询数据库数据,同时只要满足一个条件就可以取出这个对象.所以通过取出的数据肯定会有重复,所以要去掉重复项. 如果用list集合接收两次的返回对象,那么肯定是有重复对象在 ...
- 集合-2(Set(HashSet、TreeSet、LinkedHashSet)、List(ArrayList、LinkedList、Vector)、Map(HashMap、TreeMap...))
1.Set接口 集合中的元素不能重复,所以存入Set的元素都必须定义equals()来确保对象的唯一性. 无序.无索引 1.1HashSet类 实现了Set接口,此实现不是同步的. 由哈希表支持.实际 ...
- 面试官系统精讲Java源码及大厂真题 - 11 HashSet、TreeSet 源码解析
11 HashSet.TreeSet 源码解析 更新时间:2019-09-16 19:37:35 成功的奥秘在于目标的坚定. --迪斯雷利 引导语 HashSet.TreeSet 两个类是在 Map ...
- HashSet 和 TreeSet的区别
HashSet 和 TreeSet的区别 HstSet和TreeSet详解 HashSet 内部是由哈希表(实际上是一个 HashMap 实例)支持的.它不保证 set 元素的迭代顺序. TreeSe ...
- 三十九、Java集合中的HashSet和TreeSet
@Author:Runsen @Date:2020/6/6 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排名 ...
- hashSet与treeSet的去重原理
hashSet与treeSet的去重原理 1.TreeSet去重原理 :compareTo 可以实现排序及去重:如果compareTo返回0,说明是重复的,返回的是自己的某个属性和另一个对象的某个属性 ...
最新文章
- 【ACM】杭电OJ 2149
- 2018.3.23 13周5次课
- python CST中国标准时间格式转换
- bulk这个词的用法_雅思考试真题解析|雅思听力“正负含义词”的妙用
- python代码格式-pyhon代码设计格式指南
- [置顶] Objective-C,/,ios,/iphone开发基础:分类(category,又称类别)
- Bootstrap 第一篇
- 转发与重定向的区别,特点
- 去空白符的大文本字符统计(洛谷P5015题题解,Java语言描述)
- JDK8的JVM优化实操及部分原理加深理解
- Opencv的使用教程,opencv比较全的基础教程
- Android:GPS卫星定位
- 京东全球购与花王达成区块链溯源合作
- 人生就是一场与自己的较量,社科院杜兰金融硕士项目引领你走得更远
- 读书感受 之 《写给年轻人的 经济学故事书》
- Zotero+zotfile+坚果云+PDF Expert超好用的多设备协同文献管理组合(保姆级别)
- 已知银行整存整取存款不同期限的月息利率分别为: 月息利率= 0.63% 期限=1年 0.66% 期限=2年 0.69% 期限=3年 0.75% 期限=5年
- java打印pdf_java操作打印机打印pdf文件
- HCS12X微控制器的外部总线接口介绍
- 五、用矩阵键盘实现密码锁
热门文章
- 最大矩阵和 2015-05-13 21:23 8人阅读 评论(0) 收藏...
- pdf怎么转换成word文字版
- Flex 4中组件背景设置(填充方式)group为例子
- 【体系结构】一条SQL语句经历了什么
- [RMAN]异机恢复实验
- .Net中的RealProxy实现AOP
- SEO关键词优化:如何理解被百度快速索引?
- 使用JWT保护你的Spring Boot应用 - Spring Security实战
- tomocat设置首次访问时的页面
- WindowsForm如何实现类似微软project软件的甘特图?