当前位置: 首页 > news >正文

Java 23 集合框架详解:Set 接口及实现类(HashSet、TreeSet、LinkedHashSet)

📚 Java 23 集合框架详解:Set 接口及实现类(HashSetTreeSetLinkedHashSet


📖 概述

Set 是 Java 集合框架中用于存储 无序、不重复元素 的接口。它的实现类包括 HashSetTreeSetLinkedHashSet,它们在底层数据结构、排序规则和性能特性上存在显著差异。

本文将详细介绍 Set 接口及其实现类 的使用案例、底层实现、性能优化方案、多线程优化及注意事项。


🏗️ 1. Set 接口的常用实现类

实现类底层数据结构排序方式是否允许 null线程安全性
HashSet哈希表无序允许
TreeSet红黑树自然顺序/自定义排序不允许
LinkedHashSet哈希表 + 双向链表按插入顺序允许

📋 2. HashSet 详解

2.1 特点

  • 基于哈希表实现,元素按 哈希值 存储,存取效率高。
  • 不保证元素顺序
  • 允许存储一个 null
  • 插入、删除、查找操作的平均时间复杂度为 O(1)

🔧 2.2 使用案例

import java.util.HashSet;public class HashSetExample {public static void main(String[] args) {HashSet<String> set = new HashSet<>();set.add("Alice");set.add("Bob");set.add("Charlie");// 尝试添加重复元素set.add("Alice");// 遍历set.forEach(System.out::println);}
}

输出

Alice
Bob
Charlie

🛠 2.3 优化方案

  1. 指定初始容量和负载因子
    HashSet<String> set = new HashSet<>(16, 0.75f);
    
  2. 避免频繁扩容,设置合适的初始容量,减少性能开销。

⚠️ 2.4 多线程优化

HashSet线程不安全的,可以使用 Collections.synchronizedSet() 方法或 ConcurrentHashMap 来实现线程安全。

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;public class SynchronizedHashSetExample {public static void main(String[] args) {Set<String> synchronizedSet = Collections.synchronizedSet(new HashSet<>());synchronizedSet.add("Alice");synchronizedSet.add("Bob");synchronized (synchronizedSet) {synchronizedSet.forEach(System.out::println);}}
}

📋 3. TreeSet 详解

3.1 特点

  • 基于红黑树实现,元素按 自然顺序自定义顺序 排序。
  • 不允许存储 null
  • 插入、删除、查找操作的时间复杂度为 O(log n)

🔧 3.2 使用案例

import java.util.TreeSet;public class TreeSetExample {public static void main(String[] args) {TreeSet<Integer> set = new TreeSet<>();set.add(20);set.add(10);set.add(30);// 遍历set.forEach(System.out::println);}
}

输出

10
20
30
🔧 使用自定义排序
import java.util.TreeSet;
import java.util.Comparator;public class CustomTreeSetExample {public static void main(String[] args) {TreeSet<String> set = new TreeSet<>(Comparator.reverseOrder());set.add("Alice");set.add("Bob");set.add("Charlie");set.forEach(System.out::println);}
}

输出

Charlie
Bob
Alice

🛠 3.3 优化方案

  1. 避免使用 null,因为 TreeSet 不允许存储 null
  2. 选择合适的排序规则,根据业务需求使用 自然顺序自定义排序

⚠️ 3.4 多线程优化

TreeSet线程不安全的,可以使用 Collections.synchronizedSet() 来实现线程安全。

import java.util.Collections;
import java.util.TreeSet;
import java.util.Set;public class SynchronizedTreeSetExample {public static void main(String[] args) {Set<Integer> synchronizedSet = Collections.synchronizedSet(new TreeSet<>());synchronizedSet.add(10);synchronizedSet.add(20);synchronized (synchronizedSet) {synchronizedSet.forEach(System.out::println);}}
}

📋 4. LinkedHashSet 详解

4.1 特点

  • 基于哈希表和双向链表实现
  • 保留元素的插入顺序
  • 允许存储一个 null

🔧 4.2 使用案例

import java.util.LinkedHashSet;public class LinkedHashSetExample {public static void main(String[] args) {LinkedHashSet<String> set = new LinkedHashSet<>();set.add("Alice");set.add("Bob");set.add("Charlie");// 遍历set.forEach(System.out::println);}
}

输出

Alice
Bob
Charlie

🛠 4.3 优化方案

  1. 使用 LinkedHashSet 时,考虑内存占用问题,因为双向链表会占用更多内存。
  2. 适用于需要按插入顺序遍历的场景

⚠️ 4.4 多线程优化

LinkedHashSet线程不安全的,可以使用 Collections.synchronizedSet() 来实现线程安全。

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;public class SynchronizedLinkedHashSetExample {public static void main(String[] args) {Set<String> synchronizedSet = Collections.synchronizedSet(new LinkedHashSet<>());synchronizedSet.add("Alice");synchronizedSet.add("Bob");synchronized (synchronizedSet) {synchronizedSet.forEach(System.out::println);}}
}

🔄 5. 三者对比总结

特性HashSetTreeSetLinkedHashSet
底层数据结构哈希表红黑树哈希表 + 双向链表
是否允许 null
排序方式无序自然顺序/自定义排序插入顺序
插入/删除性能O(1)O(log n)O(1)
适用场景快速查找和去重排序数据集保留插入顺序

🎯 6. 选择指南

场景推荐实现类
快速查找和去重HashSet
需要排序的集合TreeSet
需要保留插入顺序的集合LinkedHashSet

⚙️ 7. 总结

  • HashSet 适用于 快速查找和去重 的场景。
  • TreeSet 适用于 需要排序的集合
  • LinkedHashSet 适用于 需要保留插入顺序的集合

相关文章:

Java 23 集合框架详解:Set 接口及实现类(HashSet、TreeSet、LinkedHashSet)

&#x1f4da; Java 23 集合框架详解&#xff1a;Set 接口及实现类&#xff08;HashSet、TreeSet、LinkedHashSet&#xff09; &#x1f4d6; 概述 Set 是 Java 集合框架中用于存储 无序、不重复元素 的接口。它的实现类包括 HashSet、TreeSet 和 LinkedHashSet&#xff0c;它…...

ARMv8架构 CortexR52+ 内核 coresight_soc400介绍

前言&#xff1a;笔者在工作中接触到了一款多核芯片&#xff0c;其采用的处理器为CortexR52&#xff0c;使用的架构为ARMv8&#xff0c;我通过CoreSight SOC-400组件完成了对该芯片烧录代码的开发。这里芯片型号就不透露了&#xff0c;本文仅介绍我自己从ARM官网上提供的R52核等…...

1.Python浅过(语法基础)

1.简介 Python是一种面向对象的解释型高级编程语言&#xff0c;是强类型的动态脚本语言。 解释型语言跨平台性比编译型语言&#xff08;如c语言&#xff09;好。 print("hello world")2.Bug,Debug 多看&#xff0c;多思考&#xff0c;多尝试、查资料、记录 3.prin…...

ioremap_nocache函数

ioremap_nocache 是 Linux 内核中用于将物理地址映射到内核虚拟地址空间的函数&#xff0c;特别是用于 I/O 内存映射&#xff0c;并且禁用缓存。 一、基本语法 void __iomem *ioremap_nocache(phys_addr_t phys_addr, size_t size); 二、基本功能 将物理内存地址映射到内核虚拟…...

【235. 二叉搜索树的最近公共祖先 中等】

题目&#xff1a; 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一…...

构建智能企业:中关村科金大模型企业知识库的技术解析与应用

在数字化转型的浪潮中&#xff0c;企业对智能化知识管理的需求日益增长。知识作为企业的核心资产&#xff0c;其高效管理和应用对于提升企业运营效率和决策质量至关重要。中关村科金大模型企业知识库凭借其强大的技术架构和广泛的应用场景&#xff0c;成为构建智能企业的重要工…...

C++进阶——用Hash封装unordered_map和unordered_set

目录 前言 源码怎么说 为什么要兼容&#xff1f; 兼容的具体做法&#xff1f; 为什么要把Key转为整数&#xff08;HashFcn&#xff09;&#xff1f; 模拟实现 一、建立框架 二、迭代器 运算符重载 迭代器兼容大法 三、[ ]重载 四、实现不能修改key 实现及测试代码 …...

b612相机 13.5.5解锁会员hook

工具 lspatch&#xff08;点击选最新版本下载&#xff09; shizuku&#xff08;点击选最新版本下载&#xff09; SimpleHook&#xff08;点击选最新版本下载&#xff09; b612&#xff08;自行百度下载&#xff09; 效果图 教程 [{"packageName":"com.camp…...

iOS - 弱引用表(Weak Reference Table)

1. 基本数据结构 // 弱引用表的基本结构 struct weak_table_t {weak_entry_t *weak_entries; // 保存所有的弱引用对象size_t num_entries; // 当前存储的弱引用数量uintptr_t mask; // 哈希表大小掩码uintptr_t max_hash_displacement; /…...

C#语言的网络编程

C#语言的网络编程 引言 随着互联网的飞速发展&#xff0c;网络编程成为了软件开发中的一个重要领域。C#语言作为一种现代编程语言&#xff0c;凭借其丰富的类库、良好的可读性和强大的功能&#xff0c;广泛应用于开发各种网络应用程序。无论是Windows应用、Web应用还是云服务…...

【操作系统】课程 4调度与死锁 同步测练 章节测验

4.1知识点导图 处理机调度与死锁相关内容的文字整理&#xff1a; 基本准则 资源利用率&#xff1a;使系统中的处理机和其他所有资源都尽可能地保持忙碌状态。系统吞吐量&#xff1a;单位时间内系统所完成的作业数。公平性&#xff1a;使各进程都获得合理的CPU时间&#xff0c;而…...

如何查看已经安装的python版本和相关路径信息

如何查看已经安装的python版本和相关路径信息 本文目录&#xff1a; 一、通过命令行模式查询 1、通过命令where python 2、通过命令print(sys.executable) 二、在 Anaconda Navigator 中 三、只安装python的环境下 一、通过命令行模式查询 同时按windowR键,输入cmd&#x…...

设计模式-结构型-适配器模式

在软件开发中&#xff0c;随着系统的不断扩展和模块的不断增加&#xff0c;往往会遇到不同模块之间接口不兼容的情况。此时&#xff0c;如果我们能通过某种方式将一个接口转化为另一个接口&#xff0c;那么开发工作将变得更加灵活和高效。适配器模式&#xff08;Adapter Patter…...

鸿蒙操作系统(HarmonyOS)

鸿蒙操作系统&#xff08;HarmonyOS&#xff09;是华为公司推出的一款面向未来、面向全场景的分布式操作系统。它旨在为用户提供一个更加智能、便捷和安全的操作环境&#xff0c;支持多种终端设备之间的无缝协作。在鸿蒙应用开发中&#xff0c;ArkUI作为官方推荐的用户界面开发…...

基于海思soc的智能产品开发(camera sensor的两种接口)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于嵌入式开发设备来说&#xff0c;除了图像显示&#xff0c;图像输入也是很重要的一部分。说到图像输入&#xff0c;就不得不提到camera。目前ca…...

解密LLM结构化输出:代码示例与原理分析

解密LLM结构化输出&#xff1a;代码示例与原理分析 一、LLM结构化输出概述 1. 结构化输出的定义与优势 结构化输出指的是语言模型&#xff08;LLM&#xff09;生成的遵循特定格式&#xff08;如JSON、XML&#xff09;的数据&#xff0c;这些数据易于解析和处理。相较于非结构…...

Go语言的数据类型

Go语言的数据类型详解 Go语言是一门具有简洁、高效并且强类型的编程语言。它的设计理念之一是让程序员能够以清晰、简明的方式表达自己的意图。在Go语言中&#xff0c;数据类型是其基础构建块之一&#xff0c;理解不同数据类型的特点和使用场景对于编写高效的Go程序至关重要。…...

复杂园区网基本分支的构建

目录 1、各主机进行网络配置。2、交换机配置。3、配置路由交换&#xff0c;进行测试。4、配置路由器接口和静态路由&#xff0c;进行测试。5、最后测试任意两台主机通信情况 模拟环境链接 拓扑结构 说明&#xff1a; VLAN标签在上面的一定是GigabitEthernet接口的&#xff0c…...

如何很快将文件转换成另外一种编码格式?编码?按指定编码格式编译?如何检测文件编码格式?Java .class文件编码和JVM运行期内存编码?

如何很快将文件转换成另外一种编码格式? 利用VS Code右下角的"选择编码"功能&#xff0c;选择"通过编码保存"可以很方便将文件转换成另外一种编码格式。尤其&#xff0c;在测试w/ BOM或w/o BOM, 或者ANSI编码和UTF编码转换&#xff0c;特别方便。VS文件另…...

《C++11》Lambda 匿名函数从入门到进阶 优缺点分析 示例

Lambda 匿名函数从入门到进阶 C11 引入了 lambda 表达式&#xff0c;这是一种非常强大的功能&#xff0c;可以让我们在代码中定义匿名函数。它们不仅使代码更加简洁&#xff0c;而且在处理回调、算法和多线程编程时极为方便。本文将带你从入门到进阶&#xff0c;全面了解 C11 …...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...