Java的HashSet vs. TreeSet vs. LinkedHashSet比较

set是用来存储没有重复的元素的。set在java中有三种比较常用实现:HashSet, TreeSet and LinkedHashSet。所以,不同的时候我们自然需要考虑如何选择使用不同的set。这就要我们对于这三种set的特点和实现有一定的了解。一般来说,如果我们需要一个存取效率比较高的set,我们可以选择hashset,如果我们需要一个可以自动给元素排序的set,我们就需要使用treeset,如果我们想要元素按插入的样子保持顺序,那么我们就可以使用LinkedHashSet。

image.png

hashset通过哈希表实现,元素是不排序的,所以输出set的时候元素的顺序是随机的,add,remove, and contains这三个方法的时间复杂度都是常数 O(1)。 treeset通过红黑树实现,元素是排好序的,但是相应的操作时间复杂度就增加了,add,remove, and contains这三个方法的时间复杂度都是 O(log (n)) LinkedHashSet is between HashSet and TreeSet. It is implemented as a hash table with a linked list running through it, so it provides the order of insertion. The time complexity of basic methods is O(1) LinkedHashSet是介于HashSet and TreeSet.之间。通过一个带链表的哈希表实现,所以它是按插入顺序排序的,保持插入的顺序,基本操作的时间复杂度和hashset一样都是常数时间。

** 注意的是,treeset由于需要对元素排序,所以添加的元素需要实现comparable或者comparator,不然就会报错 **像下面这个例子

import java.util.Iterator;
import java.util.TreeSet;

public class SetTest {

    public static void main(String[] args) {
        
        TreeSet<Dog> tree = new TreeSet<>();
        tree.add(new Dog(1));
        tree.add(new Dog(5));
        tree.add(new Dog(3));
        
        Iterator<Dog> iter = tree.iterator();
        while(iter.hasNext()) {
            System.out.println(iter.next());
        }
    }

}

class Dog {
    private int size;
    
    public Dog(int size) {
        this.size = size;
    }
    
}

image.png

我们对dog实现comparable接口就可以

class Dog implements Comparable<Dog>{
    private int size;
    
    public Dog(int size) {
        this.size = size;
    }

    @Override
    public int compareTo(Dog o) {
        return this.size - o.size;
    }
    
    public String toString() {
        return size + " ";
    }
    
}

下面我们简单的写一个小程序测试三个set的效率:

public static void main(String[] args) {
Random r = new Random();
HashSet<Dog> hashSet = new HashSet<Dog>();
TreeSet<Dog> treeSet = new TreeSet<Dog>();
LinkedHashSet<Dog> linkedSet = new LinkedHashSet<Dog>();
// start time
long startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
int x = r.nextInt(1000 - 10) + 10;
hashSet.add(new Dog(x));
}
// end time
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println("HashSet: " + duration);
// start time
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
int x = r.nextInt(1000 - 10) + 10;
treeSet.add(new Dog(x));
}
// end time
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("TreeSet: " + duration);
// start time
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
int x = r.nextInt(1000 - 10) + 10;
linkedSet.add(new Dog(x));
}
// end time
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("LinkedHashSet: " + duration);
}

image.png

image.png

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发之途

Java集合框架源码解析之HashSet

1234
来自专栏机器学习入门

LWC 52:687. Longest Univalue Path

LWC 52:687. Longest Univalue Path 传送门:687. Longest Univalue Path Problem: Given...

2337
来自专栏来自地球男人的部落格

[LeetCode] 78. Subsets

【原题】 Given a set of distinct integers, nums, return all possible subsets. Not...

2709
来自专栏码匠的流水账

聊聊storm nimbus的mkAssignments

storm-2.0.0/storm-server/src/main/java/org/apache/storm/daemon/nimbus/Nimbus.jav...

1202
来自专栏菩提树下的杨过

XStream、JAXB 日期(Date)、数字(Number)格式化输出xml

XStream、Jaxb是java中用于对象xml序列化/反序列化 的经典开源项目,利用它们将对象转换成xml时,经常会遇到日期(Date)、数字按指定格式输出...

2717
来自专栏恰童鞋骚年

数据结构基础温故-4.树与二叉树(下)

上面两篇我们了解了树的基本概念以及二叉树的遍历算法,还对二叉查找树进行了模拟实现。数学表达式求值是程序设计语言编译中的一个基本问题,表达式求值是栈应用的一个典型...

1012
来自专栏数据结构与算法

2879 堆的判断

2879 堆的判断 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 堆是一种常用...

3228
来自专栏DHUtoBUAA

找出该树中第二小的值--思路及算法实现

  在二叉树中最重要的操作莫过于遍历,即按照某一顺序访问树中的所有节点。二叉树的前序遍历、中序遍历、后序遍历都有递归和循环两种不同的实现方法。每种遍历的递归实现...

3075
来自专栏Java爬坑系列

【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解

  今天来介绍一下容器类中的另一个哈希表———》LinkedHashMap。这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap...

912
来自专栏武培轩的专栏

Java中Set集合是如何实现添加元素保证不重复的?

Java中Set集合是如何实现添加元素保证不重复的? Set集合是一个无序的不可以重复的集合。今天来看一下为什么不可以重复。 Set是一个接口,最常用的实现类就...

3877

扫码关注云+社区

领取腾讯云代金券