HashSet中的HashCode方法和equals方法的详解

简介Hash

    HashCode是一个Int型的值,其所代表的是给对应元素分配的内存地址。

    用数组的概念来理解hash算法,数组(是所有能储存一组元素最快的数据结构)。数组的每个元素都有他的索引(下标),我们如果想要访问数组指定的元素,只需要提供其相对应的索引即可。而HashCode便是HashSet的”索引“,通过索引我们便可以快速的定位、访问该元素——这也是Hash算法的价值所在:速度

    HashSet集合判断俩个元素相等的标准是俩个对象通过equals()方法比较相等,并且俩个对象返回的hashCode也相等。


关于HashCode的返回值,下图便于理解:


理解HashCode和equals之间的区别,请分析下列代码:

class A{
	int count;

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + count;
		return result;
	}

	@Override
	public String toString() {
		return "A [count=" + count + "]";
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		A other = (A) obj;
		if (count != other.count)
			return false;
		return true;
	}

	public A(int count) {
		super();
		this.count = count;
	}
}
public class HashSetDemo {
            public static void main(String[] args) {
				HashSet hs = new HashSet();
				hs.add(new A(5));
				hs.add(new A(-3));
				hs.add(new A(9));
				hs.add(new A(-2));
				System.out.println(hs);
				Iterator t = hs.iterator();         //取出第一个元素
				A first = (A) t.next();             //改变第一个元素的count值
				System.out.println(first);
				System.out.println(t.next());
				first.count=-3;
				System.out.println(hs);
				hs.remove(first);
				System.out.println(hs);
				System.out.println("hs是否包含count为-3的A对象?"+hs.contains(new A(-3)));
				System.out.println("hs是否包含count为5的A对象?"+hs.contains(new A(5)));
				
			}
}

运行结果:


原因:

        在重写的hashcode方法里面,我们可以看出来hashcode返回值直接跟count挂钩,我们也可以直接写成return count,也行。

result = prime * result + count;           //Source自动生成,参数count
		return result;

        理解为,count不同hashcode不同。

        从改变的第一个结果: [A [count=-3], A [count=9], A [count=-3], A [count=-2]]           我们可以看出来明显有俩个重复的-3,这是因为我们修改了HashSet里元素的结果。

         从改变的第二个结果: [A [count=-3], A [count=9], A [count=-2]]                                   试图删除count=-3的对象时,HashSet会计算出该对象的Hash值,再进行equals比较。而满足该条件的只有初始化为-3的第三个元素。实际上第一个元素的位置依旧为-2元素的位置,故不满足。这里也解释了,为什么同一内容(equals返回treu),而hash值不同,俩个元素依旧可以添加成功。解释如下图:



图片出处:  https://blog.csdn.net/lijiecao0226/article/details/24609559

参考文献:疯狂JAVA

猜你喜欢

转载自blog.csdn.net/qq_37334150/article/details/80377159