Java集合框架之LinkedHashSet详解

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在Java开发中,集合类是非常常用的一种数据类型。而集合类中的Set集合是一种不允许重复元素的集合。在Set集合中,除了HashSet和TreeSet之外,还有一种集合类叫做LinkedHashSet。本文将会介绍LinkedHashSet的概念,源代码解析,应用场景案例,优缺点分析,类代码方法介绍以及测试用例。

摘要

  LinkedHashSet是一种Set集合类,它是HashSet和LinkedHashMap的结合体。它既有HashSet的快速查找和不允许重复元素的特性,又有LinkedHashMap的有序性和迭代器的快速遍历特性。因此,在需要保持元素顺序的情况下,我们可以使用LinkedHashSet。

LinkedHashSet

简介

  LinkedHashSet是Java集合框架中Set接口的实现类,它继承自HashSet,并且实现了Set接口。LinkedHashSet底层是通过一个由链表和哈希表组成的数据结构来实现的。其中,链表用于保证元素插入的顺序,而哈希表用于保证元素的唯一性。

  与HashSet相比,LinkedHashSet可以保证元素的插入顺序,这是因为LinkedHashSet内部维护了一个链表来记录元素的插入顺序。与TreeSet相比,LinkedHashSet的元素不是按照自然排序或者指定的Comparator排序,而是按照插入顺序排序。

源代码解析

  LinkedHashSet的源代码中,我们可以看到它实现了Set接口,并且继承了HashSet类,HashSet又继承了AbstractSet类。而AbstractSet类实现了Set接口中的一些方法。

LinkedHashSet的构造函数如下:

public LinkedHashSet() {super();map = new LinkedHashMap<>();}public LinkedHashSet(int initialCapacity, float loadFactor) {super();map = new LinkedHashMap<>(initialCapacity, loadFactor);}public LinkedHashSet(int initialCapacity) {super();map = new LinkedHashMap<>(initialCapacity);}public LinkedHashSet(Collection<? extends E> c) {super();map = new LinkedHashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));addAll(c);
}

  可以看到,LinkedHashSet提供了多个构造函数,允许用户指定不同的初始容量和负载因子。其中,最后一个构造函数会通过调用addAll方法来添加集合中的所有元素。

在这里插入图片描述

LinkedHashSet的主要方法如下:

public boolean add(E e) {return map.put(e, PRESENT)==null;
}public boolean remove(Object o) {return map.remove(o)==PRESENT;
}public void clear() {map.clear();
}public Object clone() {LinkedHashSet<?> clone = (LinkedHashSet<?>) super.clone();clone.map = (LinkedHashMap<E,Object>) map.clone();return clone;
}

  其中,add方法和remove方法都是通过调用LinkedHashMap中的put方法和remove方法来实现的。LinkedHashMapput方法和remove方法都是基于哈希表实现的,而又通过双向链表来维护元素的插入顺序。

  除此之外,LinkedHashSet还实现了Set接口中的一些方法,如contains、isEmpty、size等方法,这些方法都是基于LinkedHashMap来实现的。LinkedHashSet还提供了迭代器、并发修改异常等特性。

如下是部分源码截图:

在这里插入图片描述

应用场景案例

  1. 维护元素的顺序: 在需要维护元素插入顺序的情况下,可以使用LinkedHashSet。例如,在一个流式处理数据的应用中,需要对元素进行去重和排序操作。

  2. 避免并发修改异常: 在多线程程序中,使用LinkedHashSet可以避免并发修改异常。例如,在一个多线程爬虫程序中,需要对爬取到的URL进行去重操作,就可以使用LinkedHashSet来避免并发修改异常。

优缺点分析

优点

  1. LinkedHashSet支持元素的快速查找和不允许重复元素的特性。

  2. LinkedHashSet具有有序性,可以保证元素的插入顺序。

  3. LinkedHashSet内部维护了一个链表,可以利用迭代器快速遍历元素。

  4. 使用LinkedHashSet可以避免并发修改异常。

缺点

  1. LinkedHashSet的性能比HashSet略低,因为LinkedHashSet需要维护链表。

  2. LinkedHashSet相对于TreeSet来说,缺少排序功能。

类代码方法介绍

构造函数

public LinkedHashSet();
public LinkedHashSet(int initialCapacity);
public LinkedHashSet(int initialCapacity, float loadFactor);
public LinkedHashSet(Collection<? extends E> c);
  • 构造函数可以指定不同的初始容量和负载因子。

基本方法

public boolean add(E e);
public boolean remove(Object o);
public void clear();
public Object clone();
  • add方法和remove方法都是通过调用LinkedHashMap中的put方法和remove方法来实现的。

  • LinkedHashSet的clone方法会返回一个包含当前元素的拷贝集合。

Set接口方法

LinkedHashSet实现了Set接口中的一些方法,如contains、isEmpty、size等方法。

迭代器

  LinkedHashSet支持迭代器,它继承了HashSet的迭代器,而HashSet的迭代器又继承了AbstractSet的迭代器。

以下是一个通过迭代器遍历LinkedHashSet中元素的例子:

// 创建一个LinkedHashSet
LinkedHashSet<String> set = new LinkedHashSet<>();// 添加元素
set.add("apple");
set.add("banana");
set.add("orange");// 创建迭代器
Iterator<String> iterator = set.iterator();// 遍历元素
while(iterator.hasNext()) {String element = iterator.next();System.out.println(element);
}

测试用例

测试代码

以下是一个使用LinkedHashSet的测试用例,该测试用例用于统计一段文本中每个单词出现的次数:

package com.example.javase.collection;import java.util.LinkedHashSet;
import java.util.Scanner;/*** @Author ms* @Date 2023-10-22 21:41*/
public class LinkedHashSetTest {public static void main(String[] args) {// 读入文本Scanner scanner = new Scanner(System.in);String text = scanner.nextLine();// 分割单词String[] words = text.split("\\s+");// 创建集合LinkedHashSet<String> set = new LinkedHashSet<>();// 统计每个单词出现的次数int[] count = new int[words.length];for (int i = 0; i < words.length; i++) {if (!set.contains(words[i])) {set.add(words[i]);}count[i] = 1;for (int j = i + 1; j < words.length; j++) {if (words[i].equals(words[j])) {count[i]++;}}}// 输出结果System.out.println("单词\t出现次数");for (String word : set) {int sum = 0;for (int i = 0; i < words.length; i++) {if (word.equals(words[i])) {sum += count[i];}}System.out.println(word + "\t" + sum);}}
}

演示结果

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

在这里插入图片描述

代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。这是一个使用 LinkedHashSet 统计给定文本中每个单词出现次数的程序。

  首先通过 Scanner 读入文本,然后使用 split 方法将文本分割成单词数组。

  接着创建一个 LinkedHashSet 集合,用于存储出现过的单词,并通过循环遍历单词数组,将每个单词存入集合中。

  接下来,遍历单词数组,统计每个单词出现的次数。通过一个 count 数组记录每个单词的出现次数,count[i] 表示第 i 个单词的出现次数,初值为 1,然后再循环遍历之后的单词数组,如果找到了相同的单词,则将当前单词的出现次数加 1。

  最后再次遍历集合中的每个单词,利用 count 数组计算每个单词出现的总次数,并输出结果。

全文小结

  本文介绍了Java集合框架中的LinkedHashSet,包括概念、源代码解析、应用场景案例、优缺点分析、类代码方法介绍和测试用例。LinkedHashSet是一种既有HashSet的快速查找和不允许重复元素特性,又有LinkedHashMap的有序性和迭代器快速遍历特性的集合类。在需要保持元素顺序的情况下,我们可以使用LinkedHashSet。

总结

  本文介绍了Java集合框架中的LinkedHashSet,它是一种既有HashSet的快速查找和不允许重复元素特性,又有LinkedHashMap的有序性和迭代器快速遍历特性的集合类。LinkedHashSet的底层是通过一个由链表和哈希表组成的数据结构来实现的,其中链表用于保证元素插入顺序,哈希表用于保证元素的唯一性。相比于HashSet,LinkedHashSet可以保证元素插入顺序;相比于TreeSet,LinkedHashSet的元素不是按照自然排序或者指定的Comparator排序,而是按照插入顺序排序。在需要维护元素插入顺序的情况下,我们可以使用LinkedHashSet。同时,使用LinkedHashSet可以避免并发修改异常。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/687296.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6个超TM好用的神仙App推荐!

1. AI文本视频生成工具——Jurilu Jurilu 是一款功能强大的 AI 文本视频生成器&#xff0c;允许用户快速将文本内容转换成极具吸引力的视频。它的使用非常简单&#xff1a;只需要输入文字&#xff0c;选择想要的样式和模板&#xff0c;Jurilu 就会自动将文字转换成生动的视频。…

【SpringBoot整合系列】SpringBoot整合RabbitMQ-消息过期(死信队列和延迟队列)

目录 业务场景传统轮询消息队列完整版 默认情况TTL&#xff08;消息的有效期&#xff09;TTL 的设置有两种不同的方式单条消息过期队列消息过期特殊情况 死信队列概述应用场景产生原因原理图死信交换机死信队列实现一下 延迟队列背景定时任务&#xff1f;延迟队列实现思路代码 …

linux - 搭建部署ftp服务器

ftp 服务: 实现ftp功能的一个服务,安装vsftpd软件搭建一台ftp服务器 ftp协议: 文件传输协议 (file transfer protocol),在不同的机器之间实现文件传输功能, 例如 视频文件下载,源代码文件下载 公司内部:弄一个专门的文件服务器,将公司里的文档资料和视频都存放…

uni-appH5Android混合开发二 || 使用Android Studio打包应用APK

前言&#xff1a; 在上一章节我们已经讲了如何uni-app离线打包Android平台教程&#xff0c;这一章就该来讲讲如何使用Android Studio打包应用APK提供给Android手机安装使用了。 uni-app跨平台框架介绍和快速入门 uni-app跨平台框架介绍和快速入门 第一步、首先打开已经编译好的…

浅谈如何自我实现一个消息队列服务器(7)——编写服务器部分

文章目录 一、编写服务器代码1.1、分析一个服务器应具备的功能1.1.1、成员变量1.1.2、对外提供的接口 一、编写服务器代码 再次拿出这张图&#xff0c;前面我们已经将重要概念&#xff1a;VirtualHost、exchange、msgQueue、message、binding 都实现了&#xff0c;此时就可以开…

【AI+换脸换装】从OpenAI 探索色情露骨内容领域浅聊AI换脸换装

5月9日消息&#xff0c;据外电报道&#xff0c;OpenAI 周三发布了文档草案&#xff0c;阐述了它希望 ChatGPT 及其其他人工智能技术如何运作。冗长的Model Spec 文件的一部分透露&#xff0c;该公司正在探索进军色情和其他露骨内容领域。 看完这个&#xff0c;心里有点惊讶&am…

以蒸馏的名义:“从去噪自编码器到生成模型”重出江湖

©PaperWeekly 原创 作者 | 苏剑林 单位 | 科学空间 研究方向 | NLP、神经网络 今天我们分享一下论文《Score identity Distillation: Exponentially Fast Distillation of Pretrained Diffusion Models for One-Step Generation》[1]&#xff0c;顾名思义&#xff0c;这是…

【HMGD】GD32/STM32 DMA接收不定长串口数据

单片机型号&#xff1a;GD32F303系列 CubeMX配置 配置串口参数 开启DMA 开启中断 示例代码 使用到的变量 uint8_t RX_Buff_FLAG 0; uint8_t RX_Buff[300] {0}; uint8_t TX_Buff[300] {0};串口接收空闲函数 // 串口接收空闲函数 void HAL_UARTEx_RxEventCallback(UART_H…

初识C语言——第十七天

选择语句&#xff1a;switch switch语句&#xff08;整型表达式&#xff09; { 语句项&#xff1a; } 而语句项是什么呢&#xff1f; //是一些case语句&#xff1a; //如下 case 整形常量表达式&#xff1b;常量可以&#xff0c;字符也可以&#xff08;因为字符存储的时…

灯珠CCD或CMOS成像RGB数据 光谱重建

1. 源由 本文主要为了通过摄像头CCD或者CMOS传感器对灯珠成像数据分析、重建灯珠可见光范围光谱数据的研究&#xff0c;从原理和方法上论证可行性。 随着照明技术迅猛发展&#xff0c;LED技术日渐成熟。LED产品由于具备经久耐用、节能且价格低等优势&#xff0c;已成为照明行…

算法学习011-不同的二叉查找树/搜索树 c++动态规划算法实现 中小学算法思维学习 信奥算法解析

目录 C不同的二叉查找树 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、运行结果 五、考点分析 六、推荐资料 C不同的二叉查找树 一、题目要求 1、编程实现 二叉查找树&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;…

STC8增强型单片机开发【定时器Timer⭐】

目录 一、引言 二、定时器基础知识 三、STC8定时器配置 四、代码示例 五、总结 一、引言 在单片机开发中&#xff0c;定时器&#xff08;Timer&#xff09;是一个极其重要的组件&#xff0c;它允许开发者基于时间触发各种事件或任务。STC8增强型单片机作为一款功能丰富的…