【浅谈Java的HashSet类】

251 阅读2分钟

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

Set集合

在说HashSet集合之前,咱们先来回顾下Set集合。 Set是Collection的一个接口。Set集合不允许包含相同的元素,并且Set集合通常不能记住元素的添加顺序。

HashSet类

HashSet是Set接口的典型实现。HashSet按Hash算法(HashMap来实现)来存储集合中的元素,因此具有很好的存取和查找性能。

HashSet具有以下特点:

1. 它不保证集合的迭代顺序
2. 此类允许null 元素
3. 此实现不是同步的。 如果多个线程同时访问一个散列集,并且至少有一个线程修改了该集,则必须在外部进行同步。

在向HashSet中添加对象时,HashSet会调用该对象的hashCode()方法,该方法返回的是一个由系统随机给出的十进制整数。(是对象模拟出来的逻辑地址值,不是数据实际存储的物理地址值)。HashSet根据该hashCode值决定该对象在HashSet中的存储位置。

HashSet集合判断两个元素是否相等的标准是通过equals方法比较相等,并且两个对象的hashCode值也相等。

来看一下具体例子:

import java.util.HashSet;
public class TestHashSet {
	public static void main(String[] args) {
		A a1 = new A();
		A a2 = new A();
		B b1 = new B();
		B b2 = new B();
		C c1 = new C();
		C c2 = new C();
		HashSet hashSet = new HashSet<String>();
		System.out.println(hashSet.add(a1));
		System.out.println(hashSet.add(a2));
		System.out.println(hashSet.add(b1));
		System.out.println(hashSet.add(b2));
		System.out.println(hashSet.add(c1));
		System.out.println(hashSet.add(c2));
	}
}

/**
 * 类A的equals始终返回true
 */
class A{
	@Override
	public boolean equals(Object o){
		return true;
	}
}

/**
 * 类B的hashCode方法始终返回1
 */
class B{
	@Override
	public int hashCode(){
		return 1;
	}
}

/**
 * 类C的equals方法始终返回true,hashCode方法始终返回2;
 */
class C{
	@Override
	public boolean equals(Object o){
		return true;
	}
	@Override
	public int hashCode(){
		return 2;
	}
}

image.png 从结果大家应该注意,把一个对象放入HashSet中,当重写了equals方法后,应该也重写hashCode方法,否则,可能会导致冲突。应尽量保证当重写的equals方法返回结果为true时,hashCode方法返回的是同一个值。

对于HashSet类中的方法,大家可以参考Java的API文档,这里不再做过多介绍,本文主要目的是让大家了解HashSet以及HsahSet的一些重要的特性。