Java集合中的LinkedHashSet源码解读

 更新时间:2023年12月29日 10:32:51   作者:理想万岁万万岁  
这篇文章主要介绍了Java集合中的LinkedHashSet源码解读,在LinkedHashMap中,双向链表的遍历顺序通过构造方法指定,如果没有指定,则使用默认顺序为插入顺序,即accessOrder=false,需要的朋友可以参考下

一、介绍

前面文章中我们从源码详细介绍了继承于HashMap的LinkedHashMap,并通过图片示例讲解了LinkedHashMap是如何在HashMap的哈希表上将各个节点通过双向链表串起来的。

也讲解了基于HashMap实现的HashSet,那么是否存在类似于LinkedHashMap原理的一种Set集合?答案是肯定的,而且是我们本篇文章要讲的LinkedHashSet

顾名思义,LinkedHashSet是基于LinkedHashMap实现的一个Set集合。

另外,本片文章虽然不长,但是对前置知识点有着很强的依赖,需要掌握的前置知识有:HashMap(必选)、红黑树(可选)、LinkedHashMap(必选)、HashSet(必选)

二、类的声明

public class LinkedHashSet<E> extends HashSet<E>
							    implements Set<E>, Cloneable, java.io.Serializable

从类的声明中可以看到

  • 继承HashSet,表示LinkedHashSet是对HashSet的扩展。
  • 实现set接口,满足Set集合的定义
  • 实现了Cloneable接口,提供了对象克隆方法,但请注意,是浅克隆。
  • 实现了Serializable接口,支持序列化。

三、构造方法

前面我们在讲HashSet的构造方法时,其中有一个构造方法我们做了特殊对待,如下所示

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

该构造方法创建的map对象的类型是LinkedHashMap,不同于其他构造方法创建的HashMap对象。

而且我们有个关键点不要忽略,在LinkedHashMap中,双向链表的遍历顺序通过构造方法指定,如果没有指定,则使用默认顺序为插入顺序,即accessOrder=false。因此,上面的构造方法所创建的LinkedHashMap对象的双向链表遍历顺序为插入顺序。

且该构造方法就是为了给其子类LinkedHashSet使用的。我们往下看

无参构造

创建LinkedHashMap实例为内部属性,并指定底层哈希表的初始容量为16,加载因子为0.75

public LinkedHashSet() {
    super(16, .75f, true);
}

指定初始容量

创建LinkedHashMap实例为内部属性,并指定底层哈希表的初始容量为initialCapacity,加载因子为0.75

public LinkedHashSet(int initialCapacity) {
    super(initialCapacity, .75f, true);
}

指定初始容量和加载因子

创建LinkedHashMap实例为内部属性,并指定底层哈希表的初始容量为initialCapacity,加载因子为loadFactor

public LinkedHashSet(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor, true);
}

通过集合构造

虽然说LinkedHashSet的底层是LinkedHashMap,但终究还是哈希表+双向链表,需要对哈希表的容量进行计算以避免频繁的扩容。

创建LinkedHashMap实例作为内部对象后,通过addAll()方法将集合中的元素逐一保存,addAll()方法作为一个批量保存模版由其父类AbstractCollection提供,其中的add()方法由父类HashSet实现,这是设计模式—模版方法的体现。

public LinkedHashSet(Collection<? extends E> c) {
    super(Math.max(2*c.size(), 11), .75f, true);
    addAll(c);
}
public boolean addAll(Collection<? extends E> c) {
    boolean modified = false;
    for (E e : c)
        if (add(e))
            modified = true;
    return modified;
}

四、最后

看了LinkedHashSet的源码后,发现它只提供了以上几个构造函数,却没有提供各个方法。

这是因为它继承于HashSet,因此HashSet中提供的方法都是可以被LinkedHashSet对象调用的,如add()、remove()、contains()等方法。所以不再过多介绍,

五、结论

  • LinkedHashSet内部维护一个LinkedHashMap对象,其底层数据结构为哈希表+链表+红黑树+双向链表
  • LinkedHashSet对内部双向链表的遍历顺序为插入顺序

到此这篇关于Java集合中的LinkedHashSet源码解读的文章就介绍到这了,更多相关LinkedHashSet源码解读内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Cloud Gateway打造可扩展的微服务网关

    Spring Cloud Gateway打造可扩展的微服务网关

    微服务网关是一个位于客户端和后端微服务之间的服务器,用于处理所有与客户端的通信,Spring Cloud Gateway都是一个值得考虑的选择,它将帮助您更好地管理和保护您的微服务,感兴趣的朋友一起看看吧
    2023-11-11
  • Java京东面试题之为什么HashMap线程不安全

    Java京东面试题之为什么HashMap线程不安全

    那天,小二去京东面试,面试官老王一上来就甩给了他一道面试题:为什么 HashMap 是线程不安全的?这个问题哪能难的住小二,这篇文章详细解答该题目
    2021-11-11
  • java编译器和JVM的区别

    java编译器和JVM的区别

    在本篇文章里小编给大家整理的是一篇关于java编译器和JVM的区别的相关内容,有兴趣的朋友们可以学习下。
    2020-12-12
  • 一文讲解如何优雅的调试jar包

    一文讲解如何优雅的调试jar包

    在现实开发过程中,现场环境永远比开发环境复杂,下面这篇文章主要给大家介绍了关于如何优雅的调试jar包的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-03-03
  • 解决mybatis plus 一对多分页查询问题

    解决mybatis plus 一对多分页查询问题

    这篇文章主要介绍了解决mybatis plus 一对多分页查询问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Java基础之动态代理Cglib详解

    Java基础之动态代理Cglib详解

    这篇文章主要介绍了Java基础之动态代理Cglib详解,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-05-05
  • SpringBoot如何通过@Profile注解配置多环境

    SpringBoot如何通过@Profile注解配置多环境

    在Spring中,可以使用配置文件的方式来指定不同环境下所需要的配置信息,本文给大家介绍SpringBoot如何通过@Profile注解配置多环境,感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • Java语言实现简单FTP软件 FTP上传下载队列窗口实现(7)

    Java语言实现简单FTP软件 FTP上传下载队列窗口实现(7)

    这篇文章主要为大家详细介绍了Java语言实现简单FTP软件,FTP上传下载队列窗口的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • 一篇文章带你搞定JAVA注解

    一篇文章带你搞定JAVA注解

    这篇文章主要介绍了详解Java注解的实现与使用方法的相关资料,希望通过本文大家能够理解掌握Java注解的知识,需要的朋友可以参考下
    2021-07-07
  • SpringBoot实现图片上传及本地访问

    SpringBoot实现图片上传及本地访问

    在SpringBoot项目中,处理静态文件访问尤其是实时更新的文件如商品图片,可通过配置WebMvcConfig将本地文件映射到URL路径上,以解决重启项目才能访问文件的问题,本文详解如何保存和访问这些文件,帮助开发者优化项目文件管理
    2022-09-09

最新评论