【Java 基础篇】Java Set 集合详解:轻松管理不重复元素

news2025/1/17 6:04:14

在这里插入图片描述

在 Java 编程中,集合是一个非常重要的概念,它允许我们有效地存储和管理一组对象。其中之一是 Set 集合,它是一种无序、不重复的数据结构,非常适合用于存储不重复的元素。本篇博客将深入探讨 Java 中的 Set 集合,从基本概念到高级用法,为您呈现全面的信息。

1. 什么是 Set 集合?

Set 是 Java 集合框架中的一部分,它代表了一个不重复元素的集合。这意味着 Set 不允许包含重复的元素,每个元素在集合中都是唯一的。Set 集合通常用于存储无序的、不重复的对象,例如一组唯一的整数或字符串。

2. 创建和初始化 Set 集合

在 Java 中,可以使用不同的实现类来创建和初始化 Set 集合。以下是一些常见的初始化方式:

Set<String> set1 = new HashSet<>(); // 使用 HashSet 初始化
Set<Integer> set2 = new TreeSet<>(); // 使用 TreeSet 初始化
Set<Double> set3 = new LinkedHashSet<>(); // 使用 LinkedHashSet 初始化

这些初始化方式分别使用了 HashSetTreeSetLinkedHashSet 作为 Set 集合的底层实现。每种实现类都有其特点,稍后我们将详细介绍它们。

3. 基本操作

3.1 添加元素

Set 集合中添加元素非常简单,使用 add 方法即可。这个方法将确保元素不重复。

Set<String> fruits = new HashSet<>();
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");

3.2 删除元素

要从 Set 集合中删除元素,可以使用 remove 方法。这将删除指定元素。

fruits.remove("香蕉");

3.3 查询元素

要查询是否包含某个元素,可以使用 contains 方法。

boolean hasApple = fruits.contains("苹果");

4. 遍历 Set 集合

遍历 Set 集合通常使用迭代器或增强的 for-each 循环。

4.1 使用迭代器

Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    System.out.println(fruit);
}

4.2 使用增强的 for-each 循环

for (String fruit : fruits) {
    System.out.println(fruit);
}

5. Set 集合的实现类

Java 提供了多种 Set 集合的实现类,每种实现类都有其独特的特点。以下是一些常见的实现类:

5.1 HashSet

HashSet 是最常用的 Set 集合实现类之一。它使用哈希表来存储元素,并提供快速的插入、删除和查询操作。但是,它不保证元素的顺序,即元素在 HashSet 中是无序的。

5.2 TreeSet

TreeSet 是基于红黑树数据结构实现的 Set 集合。它可以确保元素按照升序或降序排列,并且支持高效的元素检索、插入和删除。因此,如果需要对元素进行排序,可以选择使用 TreeSet

5.3 LinkedHashSet

LinkedHashSetHashSet 的一个子类,它在内部使用链表维护元素的顺序。因此,LinkedHashSet 保持了元素插入的顺序,可以按照插入顺序进行遍历。如果需要保持元素的插入顺序,可以选择使用 LinkedHashSet

6. Set 集合的性能考虑

在选择使用 Set 集合时,需要考虑性能。以下是一些性能方面的考虑:

  • HashSet 的性能通常比 TreeSetLinkedHashSet 更好,因为它使用哈希表,提供了快速的插入、删除和查询操作。
  • TreeSet 的性能取决于元素的排序顺序,插入和删除操作通常较慢。
  • LinkedHashSet 的性能类似于 HashSet,但它还会维护元素的插入顺序。

选择适合您需求的实现类是非常重要的,要根据具体场景来决定。

7. 使用注意事项

在使用 Set 集合时,需要注意以下事项:

  • Set 不允许重复元素,因此添加重复元素将被忽略。
  • Set 集合通常不保证元素的顺序,如果需要顺序,请考虑使用 LinkedHashSetTreeSet
  • Set 集合不是线程安全的,如果在多线程环境中使用,需要考虑同步操作或使用线程安全的集合实现。

8. 高级用法

8.1 Set 集合的操作

Set 集合支持一系列集合操作,如并集、交集和差集。可以使用 addAllretainAllremoveAll 等方法来执行这些操作。

Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> set2 = new HashSet<>(Arrays.asList(2, 3, 4));

// 求并集
Set<Integer> union = new HashSet<>(set1);
union.addAll(set2);

// 求交集
Set<Integer> intersection = new HashSet<>(set1);
intersection.retainAll(set2);

// 求差集
Set<Integer> difference = new HashSet<>(set1);
difference.removeAll(set2);

8.2 Set 集合的转换

Set 集合可以轻松地与其他集合类型进行转换。例如,将 Set 转换为数组或列表,或者将数组或列表转换为 Set

Set<String> set = new HashSet<>(Arrays.asList("apple", "banana", "cherry"));

// 将 Set 转换为数组
String[] array = set.toArray(new String[0]);

// 将 Set 转换为列表
List<String> list = new ArrayList<>(set);

// 将数组转换为 Set
Set<Integer> integerSet = new HashSet<>(Arrays.asList(1, 2, 3));

// 将列表转换为 Set
Set<Double> doubleSet = new HashSet<>(Arrays.asList(1.0, 2.0, 3.0));

8.3 Set 集合的更多用法

8.3.1 判断集合是否为空

可以使用 isEmpty() 方法来检查一个 Set 是否为空。这在需要验证集合是否包含元素时很有用。

Set<String> set = new HashSet<>();
boolean isEmpty = set.isEmpty(); // 返回 true,因为集合是空的

8.3.2 获取集合的大小

使用 size() 方法可以获取 Set 集合中元素的个数。

Set<String> set = new HashSet<>();
int size = set.size(); // 返回 0,因为集合是空的

8.3.3 将集合转换为不可修改的集合

有时候,您可能希望将一个可变的 Set 集合转换为不可修改的集合,以避免不小心修改集合。可以使用 Collections.unmodifiableSet() 方法来实现这一目标。

Set<String> mutableSet = new HashSet<>();
// 添加元素到可变集合
Set<String> unmodifiableSet = Collections.unmodifiableSet(mutableSet);

// 尝试修改不可修改的集合将抛出异常
unmodifiableSet.add("新元素"); // 抛出 UnsupportedOperationException

8.3.4 使用 addAll 合并集合

如果您需要将两个 Set 集合合并成一个,可以使用 addAll 方法。

Set<String> set1 = new HashSet<>(Arrays.asList("apple", "banana"));
Set<String> set2 = new HashSet<>(Arrays.asList("banana", "cherry"));

set1.addAll(set2); // 将 set2 中的元素合并到 set1 中

System.out.println(set1); // 输出 [banana, apple, cherry]

8.3.5 使用 removeAll 删除集合中的元素

如果您需要从一个 Set 集合中删除另一个集合中的元素,可以使用 removeAll 方法。

Set<String> set1 = new HashSet<>(Arrays.asList("apple", "banana", "cherry"));
Set<String> set2 = new HashSet<>(Arrays.asList("banana", "cherry"));

set1.removeAll(set2); // 从 set1 中删除 set2 中的元素

System.out.println(set1); // 输出 [apple]

8.3.6 使用 retainAll 保留集合中的共同元素

如果您只想保留两个 Set 集合中共同的元素,可以使用 retainAll 方法。

Set<String> set1 = new HashSet<>(Arrays.asList("apple", "banana", "cherry"));
Set<String> set2 = new HashSet<>(Arrays.asList("banana", "cherry", "date"));

set1.retainAll(set2); // 保留 set1 和 set2 中的共同元素

System.out.println(set1); // 输出 [banana, cherry]

8.3.7 使用 stream() 进行操作

Java 8 引入的 Stream API 可以让您更方便地对集合进行各种操作,包括过滤、映射、聚合等。

Set<String> fruits = new HashSet<>(Arrays.asList("apple", "banana", "cherry", "date"));

// 使用 Stream 过滤元素
Set<String> filteredFruits = fruits.stream()
        .filter(fruit -> fruit.startsWith("a"))
        .collect(Collectors.toSet());

System.out.println(filteredFruits); // 输出 [apple]

8.3.8 使用 forEach 遍历元素

Java 8 引入的 forEach 方法可以方便地遍历集合中的元素。

Set<String> fruits = new HashSet<>(Arrays.asList("apple", "banana", "cherry"));

fruits.forEach(fruit -> {
    System.out.println(fruit); // 分别输出每个水果
});

这些高级用法可以帮助您更灵活地使用 Set 集合,根据具体需求选择适当的方法和技巧来处理数据。无论是处理元素的增删改查,还是进行集合操作和转换,Java 的 Set 集合提供了丰富的功能,以满足各种编程需求。

9. 示例代码

以下是一些使用 Set 集合的示例代码:

// 创建一个 HashSet
Set<String> fruits = new HashSet<>();

// 添加元素
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");

// 删除元素
fruits.remove("香蕉");

// 查询元素
boolean hasApple = fruits.contains("苹果");

// 遍历集合
for (String fruit : fruits) {
    System.out.println(fruit);
}

10. 总结

Set 集合是 Java 中一种非常有用的数据结构,用于存储不重复的元素。本博客介绍了 Set 集合的基本概念、创建和初始化、基本操作、遍历、不同实现类、性能考虑、使用注意事项、高级用法以及示例代码。希望通过本文的介绍,您对 Set 集合有了更深入的了解,并能够在实际编程中灵活运用。无论是初学者还是有经验的开发者,都可以通过掌握 Set 集合来提高代码的效率和可维护性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数电课程设计——课设二:交通信号灯

一、实验内容 &#xff08;1&#xff09;十字路口有 x、y 方向两组交通信号灯&#xff0c;每组有红、黄、绿灯各一个&#xff1b; &#xff08;2&#xff09;设计一个交通灯控制电路&#xff0c;模拟十字路口交通灯工作情况&#xff0c;红灯亮 35s&#xff0c;黄灯亮 5s&…

IP的基础知识

IP IP指网际互连协议&#xff0c;Internet Protocol的缩写&#xff0c;是TCP/IP体系中的网络层协议。 设计IP的目的是提高网络的可扩展性&#xff1a;一是解决互联网问题&#xff0c;实现网络的互联互通&#xff1b;二是解除顶层网络应用和底层网络技术之间的耦合。 根据端到端…

btree学习笔记

简介 btree&#xff1a;balance tree&#xff0c;平衡多叉树&#xff0c;类比avl&#xff1a;平衡二叉树&#xff0c;都是有平衡的属性 (多个子树高度一致)&#xff0c;只不过是二叉和多叉的区别。 使用场景 文件系统如extfs、jffs&#xff0c;sql&#xff0c;磁盘上的索引查…

VirtualBox(内有Centos 7 示例安装)

1常见概念以及软件安装 1.1 虚拟化技术&#xff1a; 虚拟化技术指的是将计算机的各种硬件资源加以抽象、转换、分割&#xff0c;最后组合 起来的技术。其目的和作用主要是打破硬件资源不可分的情况&#xff0c;方便程序员自 己集成所需资源。 1.2 Virtual Box 其是虚拟化技术作…

[源码系列:手写spring] IOC第十三节:Bean作用域,增加prototype的支持

为了帮助大家更深入的理解bean的作用域&#xff0c;特意将BeanDefinition的双例支持留到本章节中&#xff0c;创建Bean,相关Reader读取等逻辑都有所改动。 内容介绍 在Spring中&#xff0c;Bean的作用域&#xff08;Scope&#xff09;定义了Bean的生命周期和可见性。包括单例和…

【redis进阶】基础知识简要回顾

1. 常见功能介绍 聚合统计 使用list集合的差集、并集来统计 排序统计 SortedSet&#xff08;ZSet&#xff09;统计&#xff0c;再利用分页列出权重高的元素 二值状态统计 BitMap存储&#xff0c;获取并统计 SETBIT uid:sign:3000:202008 2 1 GETBIT uid:sign:3000:202008 2…

Linux动态链接懒加载

Linux动态链接懒加载 懒加载 最近一个名词——懒加载&#xff0c;是一种与动态链接相关的技术&#xff0c;我对它有点感兴趣&#xff0c;于是决定深入了解一番。 懒加载是一种延迟加载资源的策略&#xff0c;它将资源的加载推迟到在首次访问或需要时才执行。这意味着在应用程…

Paper: 利用RNN来提取恶意软件家族的API调用模式

论文 摘要 恶意软件家族分类是预测恶意软件特征的好方法&#xff0c;因为属于同一家族的恶意软件往往有相似的行为特征恶意软件检测或分类方法分静态分析和动态分析两种&#xff1a; 静态分析基于恶意软件中包含的特定签名进行分析&#xff0c;优点是分析的范围覆盖了整个代码…

【Unity3D】UI Toolkit自定义元素

1 前言 UI Toolkit 支持通过继承 VisualElement 实现自定义元素&#xff0c;便于通过脚本控制元素。另外&#xff0c;UI Toolkit 也支持将一个容器及其所有子元素作为一个模板&#xff0c;便于通过脚本复制模板。 如果读者对 UI Toolkit 不是太了解&#xff0c;可以参考以下内容…

《AI辞职信一键生成》告别凡俗套路,展现独特个性!

在这个科技日新月异的时代&#xff0c;我们的生活被各种应用软件深深地渗透。其中&#xff0c;讯飞星火AI大模型的应用无疑是一种创新和突破。最近&#xff0c;我有幸体验了一款名为《AI辞职信一键生成》的web应用&#xff0c;它以其独特的功能和出色的用户体验&#xff0c;让我…

微信小程序Day2笔记

1、WXML模板语法 1. 数据绑定 数据绑定的基本原则 在data中定义数据在WXML中使用数据 2. 在data中定义页面的数据 在页面对应的.js文件中&#xff0c;把数据定义到data对象中。 3. Mustache语法的格式 把data中的数据绑定到页面中渲染&#xff0c;使用Mustache语法&…

不推介使用裸指针的几种情况

情况一&#xff1a; //原生指针没有所有权 void f() {// 不好: 原生指针拥有了所有权int* p1 new int{7}; // ... }template<typename T> class X {public:T* p; // 不好: 不清楚 p 所有权T* q; // 不好: 不清楚 q 所有权// ... };// 不好: 不清楚返回值所有权 Gadget*…

机器学习:自然语言处理上的对抗式攻击

Attacks in NLP 相关话题 Introduction 以前的攻击专注于图像和语音上&#xff0c;而NLP上的内容比较少。而NLP的复杂度跟词典有关系&#xff1a; NLP只能在embedding后的特征上加噪声 Evasion Attacks 电影的评论情感分类&#xff0c;将film换成films后&#xff0c;评论从…

637. 二叉树的层平均值

637. 二叉树的层平均值 题目-简单难度示例1. bfs 题目-简单难度 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 示例 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&…

DQN模型

1. DQN模型 References [1] 强化学习第五节&#xff08;DQN&#xff09;【个人知识分享】_哔哩哔哩_bilibili

在MDK-Keil中开发S32K144

对于NXP的S32K1xx系列MCU&#xff0c;前面已经介绍过&#xff0c;官方有专门支持该系列MCU开发的IDE工具——S32DS&#xff0c;这个工具还有对应的代码生成配置工具&#xff0c;而且也是官方推荐使用的工具。 S32DS开发环境是基于Eclipse改写的&#xff0c;熟悉Eclipse的话可以…

python使用百度AipOCR来实现图像文字识别

上篇文字讲到了可以截屏手机模拟器上的界面并传回电脑上&#xff0c;文章链接 python将手机模拟器截屏并发送至电脑上_小小爬虾的博客-CSDN博客 传回来以后&#xff0c;就可以识别出图片中的文字内容了。 我使用的是Python3.10.4&#xff0b;百度的AipOCR库实现图像文字识别…

利用Scrum敏捷工具管理敏捷产品迭代Sprint Backlog

​什么是Sprint Backlog&#xff1f; Sprint Backlog是Scrum的主要工件之一。在Scrum中&#xff0c;团队按照迭代的方式工作&#xff0c;每个迭代称为一个Sprint。在Sprint开始之前&#xff0c;PO会准备好产品Backlog&#xff0c;准备好的产品Backlog应该是经过梳理、估算和优…

systemserver的inputdispatcher直接产生CANCEL事件原理分析-讨厌的android触摸面试题

背景回顾&#xff1a; 上一个blog已经重点讲解了app层面自己产生的Cancel触摸事件&#xff0c;大概产生的原理如下&#xff1a; 上一个blog地址&#xff1a;https://blog.csdn.net/learnframework/article/details/124086882 即可以看出来&#xff0c;在服务端systemserver其实…