【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

纯 Java 手写 TopoJSON 生成器!零依赖实战教程

纯 Java 手写 TopoJSON 生成器!零依赖实战教程

目录 前言 一、TopoJSON 核心原理极简科普 1.1 TopoJSON 与 GeoJSON 的核心区别 1.2 TopoJSON 核心结构 二、开发环境与前置准备 2.1 开发环境要求 2.2 前置知识点 三、纯 Java 代码实现 TopoJSON 生成 3.1 基础结构与构造函数 3.2 核心转换方法(GeoJSON 转 TopoJSON) 3.3 拓扑构建核心方法 3.4 辅助方法与使用示例 代码核心说明 四、总结 前言         在GIS(地理信息系统)

By Ne0inhk
4k Star|林风社交论坛:Java+Uniapp全栈开源,新手也能快速搭建多端社区

4k Star|林风社交论坛:Java+Uniapp全栈开源,新手也能快速搭建多端社区

作为开发者,你是否曾被“快速搭建多端社交论坛”的需求难住?要么技术栈复杂、部署繁琐,要么功能残缺、无法满足运营需求,要么多端适配成本高,耗费大量开发时间。今天给大家推荐一款Gitee 4.4k+ Star的开源宝藏项目——林风社交论坛(linfeng-community),基于SpringBoot+Uniapp开发,完美解决上述痛点。 先给大家上核心信息: ✨ 项目名称:林风社交论坛(linfeng-community) 📌 开源地址:https://gitee.com/virus010101/linfeng-community ⭐ Star数量:4.4k+(持续增长,社区维护活跃) 💻 核心定位:前后端分离社交论坛/BBS系统,支持小程序、H5、App、PC四端统一适配 🔧 技术栈:SpringBoot3+JDK17+MyBatis-Plus+Uniapp+Redis+WebSocket 🎯 适用人群:Java开发者、

By Ne0inhk
Java 大视界 -- Java+Spark 构建企业级用户画像平台:从数据采集到标签输出全流程(437)

Java 大视界 -- Java+Spark 构建企业级用户画像平台:从数据采集到标签输出全流程(437)

Java 大视界 -- Java+Spark 构建企业级用户画像平台:从数据采集到标签输出全流程(437) * 引言: * 正文: * 一、平台架构设计(企业级核心:解耦 + 高可用) * 1.1 架构设计原则(10 余年实战沉淀) * 1.1.1 业务驱动 * 1.1.2 分层解耦 * 1.1.3 高可用无单点 * 1.1.4 可扩展适配增长 * 1.2 技术选型决策(拒绝盲目跟风,只选对的) * 1.3 全链路架构图 * 二、数据采集层:海量数据高效接入(不丢数据、不重复) * 2.

By Ne0inhk
【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

目录 一、为什么需要 Disruptor?—— 背景与问题 二、核心设计思想 三、核心组件与原理 1. 环形缓冲区(Ring Buffer) 2. 序列(Sequence) 3. 序列屏障(Sequence Barrier) 4. 等待策略(Wait Strategy) 5. 事件处理器(EventProcessor) 6. 生产者(Producer) 四、工作流程示例(单生产者 -> 单消费者) 五、多消费者与依赖关系 六、总结:Disruptor 高性能的秘诀 一、为什么需要 Disruptor?—— 背景与问题 在高并发编程中,传统的队列(如 java.

By Ne0inhk