【Java集合】HashSet

HashSet概述

        HashSet实现了Set接口,该集合只能保存不重复的元素,元素保存的顺序并不按照存入时的顺序,HashSet经常用于元素去重,或者是检查数据集中是否有重复元素。

HashSet的实现

        HashSet是基于HashMap实现的,HashMap是键不允许重复的,这正好契合HashSet需求,用HashMap的键集来实现HashSet就再合适不过了。

构造方法

创建HashSet内部实际上创建了一个HashMap:

 public HashSet() {
    this.map = new HashMap();
}

添加元素

HashSet使用add()方法添加元素,添加成功返回true,添加失败返回false,添加失败就是添加的元素已存在,看看它是怎么实现的:

public boolean add(E var1) {
    return this.map.put(var1, PRESENT) == null;
}

添加元素实际调用了HashMap的put方法,以新增的元素作为键,PRESENT作为值,PRESENT是一个静态对象,也就是说这个内部HashMap的所有键都指向同一个值,所以不会有空间浪费,map.put(var1, PRESENT)只有键不存在时才返回空,也就代表添加成功。

删除元素

public boolean remove(Object var1) {
    return this.map.remove(var1) == PRESENT;
}

遍历HashSet

使用迭代器遍历:

HashSet<String> hashSet = new HashSet<>();
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()){
    iterator.next();
}

增强for循环是更方便的方式:

HashSet<String> hashSet = new HashSet<>();
for (String str : hashSet){
    System.out.println(str);
}

交集和差集

retainAll()方法用于求出两个集合的交集,结果保存在调用的集合内,而作为参数的集合不变:

Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer> set2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));
//求交集
set1.retainAll(set2);
//set1包含交集 {4, 5}
//set2包含交集 {4, 5, 6, 7, 8}

removeAll()方法用于求出两个集合的差集:

Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer> set2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));
// 求差集
set1.removeAll(set2); 
//set1包含差集 {1, 2, 3}
//set2包含交集 {4, 5, 6, 7, 8}

注意事项

  • HashSet 不允许重复元素,如果试图添加重复的元素,重复元素将被忽略。
  • HashSet 不保证元素的顺序,元素在 HashSet 中是无序的。
  • HashSet 是非线程安全的,如果在多线程环境下使用 HashSet,需要注意线程同步,或者考虑使用线程安全的集合类,如 ConcurrentHashSet。
  • HashSet 允许存储一个 null 元素,但通常建议避免将 null 作为有效元素存储,以免混淆和错误。
  • 在使用自定义对象作为HashSet元素时,需要正确实现 hashCode() 和 equals() 方法,以确保对象在集合中的唯一性和正确性。
  • HashSet 的性能通常是很高的,但在处理大量数据时,应注意负载因子的设置,以避免频繁的扩容操作。
  • 在迭代 HashSet 时,不要在迭代过程中修改集合的结构(添加或删除元素),否则可能会引发 ConcurrentModificationException 异常。
  • 如果只是要判断元素是否重复,在数据量大时使用BitSet会更省空间。

参考

【Java 基础篇】Java HashSet 集合详解:高效存储唯一元素的利器_51CTO博客_java集合hashset用法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值