网站首页 > java教程 正文
32.1 HashSet 的核心特性:唯一性与哈希存储
HashSet是 “去重的图书馆书架”,每本书(元素)只能放一本,且通过 “哈希编号” 快速找到书的位置。它内部基于哈希表实现,元素通过哈希值确定存储位置,天然支持去重特性。
add(E e):添加元素到集合;
size():返回集合中元素的数量;
contains(Object o):检查元素是否存在;
add(null):允许添加一个 null 值,重复添加无效。
代码示例如下:
package com.set.demo;
import java.util.Set;
import java.util.HashSet;
/**
* @author 今日头条:老陈说编程
* HashSet的基本特性及去重功能演示
* 本示例展示了HashSet的核心特性:不允许重复元素、允许null值(仅一个)、无序性
*/
public class HashSetBasicFeatures {
public static void main(String[] args) {
// 1. 创建HashSet实例
// 使用接口Set声明变量,遵循面向接口编程原则
Set<String> books = new HashSet<>();
// 2. 添加元素:add(E e)
// 向集合添加元素,如果元素已存在则返回false
// HashSet通过元素的hashCode()和equals()方法判断重复
books.add("Java核心技术");
books.add("数据结构与算法");
boolean added = books.add("Java核心技术"); // 重复元素,添加失败
System.out.println("添加重复元素结果:" + added); // 输出false
// 3. 查看集合大小:size()
// 返回集合中元素的数量(去重后)
System.out.println("集合元素数量:" + books.size()); // 输出2
// 4. 添加null值
// HashSet允许添加一个null值,重复添加无效
books.add(null);
books.add(null); // 重复null,添加失败
System.out.println("含null的集合:" + books); // 输出[null, 数据结构与算法, Java核心技术]
// 5. 检查元素存在性:contains(Object o)
// 通过hashCode()和equals()判断元素是否存在
System.out.println("包含Java书:" + books.contains("Java核心技术")); // 输出true
}
}
32.2 增删查:HashSet 的核心操作
操作HashSet就像 “管理哈希货架”—— 上架(add)时自动去重,下架(remove)时按 “哈希编号” 快速定位,查看(contains)时无需遍历整个货架!
add (E e):将元素添加到集合中,添加成功返回 true,元素已存在返回 false;
remove (Object o):从集合中移除指定元素,成功移除返回 true,否则返回false;
contains (Object o),检查元素是否存在于集合中,有返回true,否则返回false;
遍历集合:增强 for 循环、迭代器,不保证插入顺序,取决于内部哈希表的实现。
代码示例如下:
package com.set.demo;
import java.util.Set;
import java.util.HashSet;
/**
* @author 今日头条:老陈说编程
* HashSet的增删改查操作及去重逻辑演示
* 本示例展示了HashSet的基本操作:添加、删除、查询、遍历,以及去重机制
*/
public class HashSetOperations {
public static void main(String[] args) {
// 1. 创建HashSet存储整数
// HashSet内部使用HashMap实现,元素存储在HashMap的key中
Set<Integer> numbers = new HashSet<>();
// 2. 添加元素:add(E e)
// 向集合添加元素,如果元素已存在则返回false
// Integer的hashCode由值本身决定,相同值的Integer哈希码相同
numbers.add(10);
numbers.add(20);
numbers.add(30);
System.out.println("初始集合:" + numbers); // 输出顺序不固定,如[20, 10, 30]
// 3. 添加重复元素(去重)
// 重复添加相同值的Integer会被去重
numbers.add(10);
System.out.println("去重后集合:" + numbers); // 仍为[20, 10, 30]
// 4. 删除元素:remove(Object o)
// 删除指定元素,成功删除返回true,否则返回false
boolean removed = numbers.remove(20);
System.out.println("删除20:" + removed + ",剩余集合:" + numbers); // true, [10, 30]
// 5. 检查元素存在性:contains(Object o)
// 通过hashCode和equals判断元素是否存在
System.out.println("包含10:" + numbers.contains(10)); // true
System.out.println("包含5:" + numbers.contains(5)); // false
// 6. 遍历集合(无序)
// 使用增强for循环遍历集合,顺序由内部哈希表决定
System.out.println("遍历集合:");
for (Integer num : numbers) {
System.out.println(num);
}
}
}
32.3 遍历方式:迭代器与增强 for 循环
遍历HashSet就像 “按哈希货架顺序取书”,由于元素位置由哈希值决定,遍历顺序可能与插入顺序不同。推荐用迭代器或增强 for 循环,不支持按索引访问(因无序)。
增强 for 循环:代码简洁,适用于简单遍历场景,仅读取集合元素,不进行修改
迭代器(Iterator):支持遍历时安全删除元素,可实现双向遍历
代码示例如下:
package com.set.demo;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
/**
* @author 今日头条:老陈说编程
* HashSet的遍历方式及安全删除演示
* 本示例展示了HashSet的三种遍历方式,并演示了迭代器的安全删除操作
*/
public class HashSetTraversal {
public static void main(String[] args) {
Set<String> fruits = new HashSet<>();
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橘子");
fruits.add("葡萄");
// 1. 增强for循环(简洁,推荐)
// 优点:代码简洁,适用于只读操作
// 缺点:遍历过程中不能修改集合结构(增删元素)
System.out.println("增强for循环遍历:");
for (String fruit : fruits) {
System.out.println(fruit);
}
// 2. 迭代器遍历(可安全删除)
// 优点:支持在遍历过程中安全删除元素
// 原理:迭代器内部维护了对集合修改次数的检查
System.out.println("\n迭代器遍历并删除:");
Iterator<String> it = fruits.iterator();
while (it.hasNext()) {
String fruit = it.next();
if (fruit.equals("香蕉")) {
it.remove(); // 安全删除当前元素,不会触发ConcurrentModificationException
}
}
System.out.println("删除后集合:" + fruits); // 输出[苹果, 橘子, 葡萄]
// 3. 不推荐的遍历方式:转为数组后遍历(效率较低)
// 缺点:需要额外空间存储数组,且失去了集合动态特性
System.out.println("\n转为数组遍历:");
Object[] fruitArray = fruits.toArray();
for (Object fruit : fruitArray) {
System.out.println(fruit);
}
}
}
总结:HashSet 的适用场景
需要元素唯一性:如去重处理、统计不重复数据(用户 ID、商品编号等);
快速查找场景:比LinkedList的contains()方法效率高;
无序数据存储:若需要有序,可使用LinkedHashSet(维护插入顺序)或TreeSet(自动排序);
下期将讲解集合中的TreeSet,记得点赞关注,评论区留下你遇到的HashSet问题,我们一起解决!
猜你喜欢
- 2025-07-28 JDBC规范五-ResultSet详解(jdbc resultset fetchsize)
- 2025-07-28 Redis教程——数据类型(哈希、集合)
- 2025-07-28 Mybatis框架学习指南-第六节内容(常用的注解)
- 2025-07-28 用车按键指南:SET按键在汽车中的作用及操作流程详解!
- 2025-07-28 JSP request.setAttribute()详解及实例
- 2025-07-28 每天五分钟学习redis之SET命令(redis setns)
- 2025-07-28 python必须掌握的20个核心函数——set()函数
- 2025-07-28 JAVA迭代器模式适用场景优缺点是什么你知道吗,...
- 2025-07-28 redis set 详解(redis set 操作)
- 2025-07-28 Python学不会来打我(12)集合set详解:用法、场景与类型转换
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)