【java】Set接口详解

【java】Set接口详解

Java 中 Set 接口详解:特性、用法与常见坑点

一、什么是 Set?

Set 是 Java 集合框架中的一个接口,它继承自 Collection,用于存储不重复的元素

一句话概括 Set:

Set 是一个 不允许重复元素、通常不关心顺序 的集合。

Set 的核心特性(面试高频)

  1. 元素唯一性
    • 不允许存储重复元素
    • “重复”的判断依赖于 equals()(以及某些实现中的 hashCode()
  2. 最多只存在一个 null
    • 接口层面允许 null
    • 是否支持、支持几个,由具体实现决定(这里只记结论即可)
  3. 无索引、不可通过下标访问
    • 没有 get(int index)
    • 只能通过迭代器或增强 for 遍历

二、Set 的基本使用方式

1. 声明与创建

Set<Integer> set =newHashSet<>();

⚠️ 注意:Set 是接口,不能直接 new Set()


三、Set 能存哪些数据类型?

1. 不能使用基本类型

Set 的泛型参数 必须是引用类型,不能是基本类型。

// ❌ 编译错误Set<int> set =newHashSet<>();

2. 基本类型 → 包装类型对照表(必背)

int → Integerchar → Characterboolean → Booleanbyte → Byteshort → Shortlong → Longfloat → Floatdouble → Double

3. 常见可用类型示例

// 包装类型Set<Integer> intSet =newHashSet<>();Set<Character> charSet =newHashSet<>();// 字符串Set<String> strSet =newHashSet<>();// 自定义对象Set<MyClass> objSet =newHashSet<>();// 集合类型Set<List<String>> listSet =newHashSet<>();Set<Set<Integer>> setOfSets =newHashSet<>();

4. 特殊但合法的类型

// 枚举Set<DayOfWeek> enumSet =newHashSet<>();// 接口Set<Runnable> interfaceSet =newHashSet<>();// 数组(⚠️ 不推荐)Set<int[]> arraySet =newHashSet<>();
⚠️ 数组作为 Set 元素时,equals()hashCode() 行为特殊,非常容易踩坑,实际开发中应避免。

四、自动装箱与拆箱(Java 5+)

Set<Integer> set =newHashSet<>(); set.add(10);// 自动装箱:int → Integerint num = set.iterator().next();// 自动拆箱:Integer → int
面试中经常会问:
为什么 Set 不能存 int,但可以 add(10)?
→ 因为发生了自动装箱。

五、Set 的常用方法(接口层面)

1. 添加元素

set.add(1); set.add(2);
  • 如果元素已存在,add() 返回 false
  • 不会抛异常,只是“加不进去”

2. 判断元素是否存在:contains

boolean exists = set.contains(a);
  • 本质语义:Set 中是否存在与 a 相等的元素
  • 判断依据是 equals()
📌 这是算法题和业务代码中极其常用的方法

3. 删除元素

set.remove(a);
  • 删除成功返回 true
  • 元素不存在返回 false

4. 获取元素个数

int size = set.size();

5. 判空

set.isEmpty();

六、Set 的遍历方式

1. 增强 for(最常用)

for(Integer x : set){System.out.println(x);}
  • 底层仍然是 Iterator
  • 遍历过程中不能修改 Set

2. Iterator 遍历(可安全删除)

Iterator<Integer> it = set.iterator();while(it.hasNext()){Integer x = it.next();if(x ==10){ it.remove();// 唯一安全删除方式}}

七、Set 中“不重复”的真正含义(面试重点)

1. 什么叫“重复”?

Set 认为两个元素重复,当且仅当:

2. 对自定义对象尤其重要

Set<Person> set =newHashSet<>(); set.add(newPerson("Tom",18)); set.add(newPerson("Tom",18));
  • 如果 Person没有重写 equals()
    • Set 会认为这是两个不同对象
  • 接口语义层面:
    Set 依赖 equals 来保证唯一性
⚠️ 这是 Set 使用中最核心、最容易被问的问题之一

八、Set 与 List 的核心区别(接口层面对比)

维度SetList
是否允许重复❌ 不允许✅ 允许
是否有索引❌ 无✅ 有
访问方式遍历 / containsget(index)
顺序语义接口不保证接口保证
适合场景去重、判存在有序存储、按位置访问

九、常见错误与注意事项

判断存在用 contains,不要自己遍历

set.contains(a);// ✅ 语义清晰、效率更好

遍历时不能直接修改 Set

for(Integer x : set){ set.remove(x);// ❌ ConcurrentModificationException}

Set 不能用下标访问

set.get(0);// ❌ 编译错误

十、总结

关于 Set 接口,你至少要掌握:

  1. Set 是不允许重复元素的集合接口
  2. 不支持索引访问,只能遍历
  3. 泛型必须是引用类型(包装类)
  4. 判重依赖 equals()
  5. 常用方法:add / remove / contains / size
  6. 遍历推荐增强 for,删除用 Iterator
  7. Set 的核心价值:去重 + 判存在

Read more

手写一个C++ TCP服务器实现自定义协议(顺便解决粘包问题)

手写一个C++ TCP服务器实现自定义协议(顺便解决粘包问题)

在之前的博客中,我们了解了关于UDP和TCP的网络编程,直观的感受了一下网络套接字是如何使用的,并且成功的完成了客户端与服务端的网络通信,但是其中还有一个小细节我们可能会忽略,就是UDP是基于数据报进行传输的,一下子就将所有我们要发送的信息传送给对方,但是我们的TCP可是基于字节流进行传输的,我们如何保证读取上来的数据,是一个完整的报文呢? 我们在进行TCP网络通信的时候,通过调用connec函数调用,使客户端可以和服务端保持链接之后,客户端将自己想要发送的数据通过write系统调用写进对应的socket函数调用给我们返回的文件描述符所对应的文件中。 现在有一个问题就是我们向文件中写入的时候,直接将其放入即可,但是想要往出拿的时候就有点困难了,想要往出拿的人如果不知道放的人是如何放的,就会造成一系列的错误,这就好比放数据时先放了一个整形,又放了一个浮点数,还放了一个字符串,然而拿的人按照字符串,整形,浮点数这样的方式进行获取,这就会导致数据不一致的现象,所以一旦我们要发送一些带有结构化的数据时,就必须再次制定——协议,这样才能满足我们想要返送一些结构化数据的需求。 TCP是传输控

By Ne0inhk
千面之法: 释放 C++ 多态的灵活威力

千面之法: 释放 C++ 多态的灵活威力

目录 1:多态的概念 1.1:概念 2.多态的定义与实现 2.1:多态的构成条件 2.2:虚函数 2.3:虚函数的重写 2.3.1:虚函数重写的两个例外 2.3.1.1:协变(基类与派生类函数的返回值不同,基类虚函数返回基类对象的指针或引用,派生类虚函数返回派生类对象的指针或引用时) 2.3.1.2:析构函数的重写 2.4:C++11 override和final 2.4.1:final关键字 2.4.2:override关键字 2.5:重载、

By Ne0inhk
蓝桥杯手把手教你备战(C/C++ B组)(最全面!最贴心!适合小白!)

蓝桥杯手把手教你备战(C/C++ B组)(最全面!最贴心!适合小白!)

比赛环境:网盘资源分享 通过网盘分享的文件:蓝桥杯比赛环境 链接: https://pan.baidu.com/s/1eh85AW-y83ibCmEo8ByBwA?pwd=1234 提取码: 1234 1 常见问题答疑 1.1 蓝桥杯含金量高不高? 说起蓝桥杯,不得不提ACM。 ACM是国际大学生程序设计竞赛(ACM-ICPC),被誉为计算机领域的“奥运会”,是世界上,规模最大、水平最高、最具影响力的国际大学生程序设计竞赛。 ACM难度较高,当然含金量也更高, 那么蓝桥杯的含金量肯定比不过ACM,但是其具有独特的优势。 蓝桥杯难度更低,更易拿奖,同时在计算机行业具有较高认可度。 ACM适合那些智商高或者编程经验丰富(学习算法1年以上)的选手参赛。而蓝桥杯适合小白,适合期望快速获得编程领域一个认可证书而没有太多时间投入的参赛者。 1.2 获奖到底难不难? 蓝桥杯分为省赛和国赛。 省赛时: 与你竞争的是同省的人,所以获奖难度与你所在的省份有一定关系。 强省(

By Ne0inhk
深入解析C++驱动开发实战:优化高效稳定的驱动应用

深入解析C++驱动开发实战:优化高效稳定的驱动应用

深入解析C++驱动开发实战:优化高效稳定的驱动应用 在现代计算机系统中,驱动程序(Driver)扮演着至关重要的角色,作为操作系统与硬件设备之间的桥梁,驱动程序负责管理和控制硬件资源,确保系统的稳定与高效运行。随着设备复杂度的增加和系统性能需求的提升,如何使用C++高效、稳定地开发驱动程序,成为开发者亟需解决的关键问题。本文将深入探讨C++驱动开发中的常见问题及其优化策略,通过详细的示例代码,帮助开发者构建高性能、稳定可靠的驱动应用。 🧑 博主简介:ZEEKLOG博客专家、ZEEKLOG平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用,熟悉DICOM医学影像及DICOM协议,业余时间自学JavaScript,Vue,qt,python等,具备多种混合语言开发能力。撰写博客分享知识,致力于帮助编程爱好者共同进步。欢迎关注、交流及合作,

By Ne0inhk