Java中HashSet的学习

本文详细介绍了HashSet的特点,包括非同步性、允许使用null元素、多线程下的同步需求及其实现方式,并通过实例演示了HashSet输出可能呈现的偶然有序现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashSet是非同步的,允许使用null元素。如果多个线程同时访问一个Hashset,而其中至少一个线程修改了该set,那么它必须保持外部同步。这通常是通过对自然封装该set的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSet方法来“包装”set。最好在创建时完成这一操作,以防止对该set进行意外的不同步访问:

Set s = Collections.synchronizedSet(new HashSet(...));


在某些时候HashSet<Integer>的输出会恰好是有序的,这是因为插入HashSet的是Integer,其hashCode()实现就返回int值本身。所以在对象hashCode这一步引入了巧合的“按大小排序”。然后HashMap.hash(Object)获取了对象的hashCode()之后会尝试进一步混淆。所以在HashSet中,不保证有序与保证无序是不等价的。


// 代码实现
import java.util.HashSet;
import java.util.Iterator;

public class TestHashSet {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HashSet<Integer> set = new HashSet<>();
		set.add(30000000);
		set.add(50000000);
		set.add(40000000);
		set.add(10000000);
		set.add(20000000);
		// Java的HashSet是不保证有序,而与保证无序不等价
		Iterator it = set.iterator();
		while(it.hasNext()) {
			System.out.print((Integer)it.next() + (it.hasNext() ? ", ": ""));
		}
		System.out.println();
		for(Integer e : set) {
			System.out.print(e + ", ");
		}
		System.out.println();
		System.out.println("contains 10000000: " + set.contains(10000000));
	}


参考资料:

Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例

Java遍历HashSet为什么输出是有序的? -知乎


继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值