使用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相关推荐

  1. HashSet、TreeSet和LinkedHashSet

    Set不能包含重复的元素.有三个通用的set接口的实现:HashSet.TreeSet和LinkedHashSet.什么时候用以及用哪个是一个重要的问题.总体来说,如果要一个快速的集合,就用HashS ...

  2. Java容器源码分析-HashSet vs TreeSet vs LinkedHashSet

    2019独角兽企业重金招聘Python工程师标准>>> 这几天看了下容器的源码,总结一下HashSet vs TreeSet vs LinkedHashSet的区别, 如下图,col ...

  3. Set 、HashSet、TreeSet、LinkedHashSet、EnumSet

    Set 底层原理: java中set及其子类都是由对应的Map实现的,如HashSet由HashMap实现,TreeSet由TreeMap实现等等. private static final Obje ...

  4. HashSet 与TreeSet和LinkedHashSet的区别

    今天项目开发,需要通过两个条件去查询数据库数据,同时只要满足一个条件就可以取出这个对象.所以通过取出的数据肯定会有重复,所以要去掉重复项. 如果用list集合接收两次的返回对象,那么肯定是有重复对象在 ...

  5. 集合-2(Set(HashSet、TreeSet、LinkedHashSet)、List(ArrayList、LinkedList、Vector)、Map(HashMap、TreeMap...))

    1.Set接口 集合中的元素不能重复,所以存入Set的元素都必须定义equals()来确保对象的唯一性. 无序.无索引 1.1HashSet类 实现了Set接口,此实现不是同步的. 由哈希表支持.实际 ...

  6. 面试官系统精讲Java源码及大厂真题 - 11 HashSet、TreeSet 源码解析

    11 HashSet.TreeSet 源码解析 更新时间:2019-09-16 19:37:35 成功的奥秘在于目标的坚定. --迪斯雷利 引导语 HashSet.TreeSet 两个类是在 Map ...

  7. HashSet 和 TreeSet的区别

    HashSet 和 TreeSet的区别 HstSet和TreeSet详解 HashSet 内部是由哈希表(实际上是一个 HashMap 实例)支持的.它不保证 set 元素的迭代顺序. TreeSe ...

  8. 三十九、Java集合中的HashSet和TreeSet

    @Author:Runsen @Date:2020/6/6 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘课严重,专业排名 ...

  9. hashSet与treeSet的去重原理

    hashSet与treeSet的去重原理 1.TreeSet去重原理 :compareTo 可以实现排序及去重:如果compareTo返回0,说明是重复的,返回的是自己的某个属性和另一个对象的某个属性 ...

最新文章

  1. 【ACM】杭电OJ 2149
  2. 2018.3.23 13周5次课
  3. python CST中国标准时间格式转换
  4. bulk这个词的用法_雅思考试真题解析|雅思听力“正负含义词”的妙用
  5. python代码格式-pyhon代码设计格式指南
  6. [置顶] Objective-C,/,ios,/iphone开发基础:分类(category,又称类别)
  7. Bootstrap 第一篇
  8. 转发与重定向的区别,特点
  9. 去空白符的大文本字符统计(洛谷P5015题题解,Java语言描述)
  10. JDK8的JVM优化实操及部分原理加深理解
  11. Opencv的使用教程,opencv比较全的基础教程
  12. Android:GPS卫星定位
  13. 京东全球购与花王达成区块链溯源合作
  14. 人生就是一场与自己的较量,社科院杜兰金融硕士项目引领你走得更远
  15. 读书感受 之 《写给年轻人的 经济学故事书》
  16. Zotero+zotfile+坚果云+PDF Expert超好用的多设备协同文献管理组合(保姆级别)
  17. 已知银行整存整取存款不同期限的月息利率分别为: 月息利率= 0.63% 期限=1年 0.66% 期限=2年 0.69% 期限=3年 0.75% 期限=5年
  18. java打印pdf_java操作打印机打印pdf文件
  19. HCS12X微控制器的外部总线接口介绍
  20. 五、用矩阵键盘实现密码锁

热门文章

  1. 最大矩阵和 2015-05-13 21:23 8人阅读 评论(0) 收藏...
  2. pdf怎么转换成word文字版
  3. Flex 4中组件背景设置(填充方式)group为例子
  4. 【体系结构】一条SQL语句经历了什么
  5. [RMAN]异机恢复实验
  6. .Net中的RealProxy实现AOP
  7. SEO关键词优化:如何理解被百度快速索引?
  8. 使用JWT保护你的Spring Boot应用 - Spring Security实战
  9. tomocat设置首次访问时的页面
  10. WindowsForm如何实现类似微软project软件的甘特图?