Java中HashSet、LinkedHashSet和TreeSet区别详解

 更新时间:2023年09月05日 10:00:51   作者:CodingALife  
这篇文章主要介绍了Java中HashSet、LinkedHashSet和TreeSet区别详解,如果你需要一个访问快速的Set,你应该使用HashSet,当你需要一个排序的Set,你应该使用TreeSet,当你需要记录下插入时的顺序时,你应该使用LinedHashSet,需要的朋友可以参考下

HashSet、LinkedHashSet、TreeSet区别

如果你需要一个访问快速的Set,你应该使用HashSet;当你需要一个排序的Set,你应该使用TreeSet;当你需要记录下插入时的顺序时,你应该使用LinedHashSet。

HashSet是采用hash表来实现的。其中的元素没有按顺序排列,add()、remove()以及contains()等方法都是复杂度为O(1)的方法。

TreeSet是采用树结构实现(红黑树算法)。元素是按顺序进行排列,但是add()、remove()以及contains()等方法都是复杂度为O(log (n))的方法。

它还提供了一些方法来处理排序的set,如first(), last(), headSet(), tailSet()等等。

LinkedHashSet介于HashSet和TreeSet之间。它也是一个hash表,但是同时维护了一个双链表来记录插入的顺序。基本方法的复杂度为O(1)。

一、HashSet

  • 不能保证元素的排列顺序,顺序有可能发生变化
  • 不是同步的,非线程安全
  • 集合元素可以是null,但只能放入一个null
  • 当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
  • 简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等
  • 注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作
  • equals比较标准的属性,都应该用来计算hashCode的值。

二、LinkedHashSet

nkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

  1. LinkedHashSet中不能有相同元素,可以有一个Null元素,元素严格按照放入的顺序排列。
  2. LinkedHashSet如何保证有序和唯一性?
    • 底层数据结构由哈希表和链表组成。
    • 链表保证了元素的有序即存储和取出一致,哈希表保证了元素的唯一性。
  3. 添加、删除操作时间复杂度都是O(1)。
  4. 非线程安全

三、TreeSet

TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。

TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。

向TreeSet中加入的应该是同一个类的对象。

TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0

自然排序

自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。

定制排序

自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法

1.TreeSet是中不能有相同元素,不可以有Null元素,根据元素的自然顺序进行排序。

2.TreeSet如何保证元素的排序和唯一性?

底层的数据结构是红黑树(一种自平衡二叉查找树)

3.添加、删除操作时间复杂度都是O(log(n))

4.非线程安全

TreeSet排序如下

public class Person3 {
    private int age;
    private String name;
    public Person3(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    public static void main(String[] args) {
        Set<Person3> set = new TreeSet<>(new Comparator<Person3>() {
            @Override
            public int compare(Person3 o1, Person3 o2) {
                if(o1 == null || o2 == null){
                    return 0;
                }
                return o1.age - o2.age;
            }
        });
        set.add(new Person3("zzh",18));
        set.add(new Person3("jj",17));
        set.add(new Person3("qq",19));
        set.add(new Person3(null,19));
        //[Person{age=17, name='jj'}, Person{age=18, name='zzh'}, Person{age=19, name='qq'}]
        System.out.println(set);
    }

四.总结

通过以上特点可以分析出,三者都保证了元素的唯一性,如果无排序要求可以选用HashSet;

如果想取出元素的顺序和放入元素的顺序相同,那么可以选用LinkedHashSet。如果想插入、删除立即排序或者按照一定规则排序可以选用TreeSet。

到此这篇关于Java中HashSet、LinkedHashSet和TreeSet区别详解的文章就介绍到这了,更多相关HashSet、LinkedHashSet和TreeSet内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring MVC中处理ajax请求的跨域问题与注意事项详解

    Spring MVC中处理ajax请求的跨域问题与注意事项详解

    跨域问题是我们大家在开发中会经常遇到的一个问题,所以下面这篇文章主要给大家介绍了关于Spring MVC中处理ajax请求的跨域问题与注意事项的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • java ssm框架实现分页功能的示例代码(oracle)

    java ssm框架实现分页功能的示例代码(oracle)

    这篇文章主要介绍了java ssm框架实现分页功能的示例代码(oracle),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 使用Logback日志保存到相对路径的操作

    使用Logback日志保存到相对路径的操作

    这篇文章主要介绍了使用Logback日志保存到相对路径的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • MyBatis实现物理分页的实例

    MyBatis实现物理分页的实例

    这篇文章主要介绍了MyBatis实现物理分页的实例,MyBatis使用RowBounds实现的分页是逻辑分页,有兴趣的可以了解一下。
    2017-01-01
  • ByteArrayOutputStream简介和使用_动力节点Java学院整理

    ByteArrayOutputStream简介和使用_动力节点Java学院整理

    ByteArrayOutputStream 是字节数组输出流。它继承于OutputStream。这篇文章主要介绍了ByteArrayOutputStream简介和使用,需要的朋友可以参考下
    2017-05-05
  • Spring Boot 中的 Spring Cloud Feign的原理解析

    Spring Boot 中的 Spring Cloud Feign的原

    Spring Cloud Feign 是 Spring Cloud 中的一个组件,它可以帮助我们实现声明式的 REST 客户,这篇文章主要介绍了Spring Boot 中的 Spring Cloud Feign,需要的朋友可以参考下
    2023-07-07
  • JavaWeb学习笔记之Filter和Listener

    JavaWeb学习笔记之Filter和Listener

    这篇文章主要给大家介绍了关于JavaWeb学习笔记之Filter和Listener的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Java 中比较对象的用法小结

    Java 中比较对象的用法小结

    在 Java 中,比较对象的方法有多种多样,每种都有其适用的场景,通过深入理解 equals() 方法、Comparable 接口和 Comparator 接口,我们能够更好地处理对象之间的比较,使代码更加灵活、清晰和健壮,本文给大家介绍Java 中比较对象的用法,感兴趣的朋友一起看看吧
    2023-12-12
  • java随机字符补充版

    java随机字符补充版

    今天在zuidaimai看到一个java随机字符生成demo,正好要用,但发现不完整,重新整理一下,分享给有需要的朋友
    2014-01-01
  • Spring Cloud根据服务名获取服务的ip端口问题

    Spring Cloud根据服务名获取服务的ip端口问题

    这篇文章主要介绍了Spring Cloud根据服务名获取服务的ip端口,本篇示例我就以Nacos注册中心为例了,下面是我注册的两个服务,需要的朋友可以参考下
    2022-09-09

最新评论