Java:hashCode()和equals()的contains,Set方法的协定

本文是关于hashCode的,它等于Set中用于contains(Object o)方法的协定。
关于使用Set中的contains()方法的一个难题
import java.util.HashSet;
class Dog{
String color;

public Dog(String s){
	color = s;
}	}

public class SetAndHashCode {
public static void main(String[] args) {
HashSet dogSet = new HashSet();
dogSet.add(new Dog(“white”));
dogSet.add(new Dog(“white”));

	System.out.println("We have " + dogSet.size() + " white dogs!");

	if(dogSet.contains(new Dog("white"))){
		System.out.println("We have a white dog!");
	}else{
		System.out.println("No white dog!");
	}	
}}

输出:
We have 2 white dogs!
No white dog!
我们向集合中添加了两只白狗-dogSet,大小显示我们有2只白狗。但是,为什么在使用contains()方法时没有白狗呢?
Set的contains(Object o)方法
从Java Doc中,当且仅当此集合包含元素e使得(o == null?e == null:o.equals(e))时,contains()方法返回true。因此,contains()方法实际上使用equals()方法检查相等性。
注意,可以将null作为元素添加到集合中。以下代码实际上显示true。
HashSet a = new HashSet();
a.add(null);if(a.contains(null)){
System.out.println(“true”);}
所述公共布尔等于(对象OBJ)方法在对象类中定义。每个类(包括您自己定义的类)都将Object作为超类,并且它是任何类层次结构的根。所有对象(包括数组)都实现此类的方法。
在您自己定义的类中,如果不显式重写此方法,它将具有默认实现。当且仅当两个对象引用同一个对象(即x == y为true)时,它才返回true。
如果将Dog类更改为以下类别,它将起作用吗?
class Dog{
String color;

public Dog(String s){
	color = s;
}

//overridden method, has to be exactly the same like the following
public boolean equals(Object obj) {
	if (!(obj instanceof Dog))
		return false;	
	if (obj == this)
		return true;
	return this.color.equals(((Dog) obj).color);
}

}
答案是不。
现在问题是由Java中的hashCode和equals contract引起的。hashCode()方法是Object类中的另一个方法。
约定是,如果两个对象相等(通过使用equals()方法),则它们必须具有相同的hashCode()。如果两个对象具有相同的哈希码,则它们可能不相等。
public int hashCode()的默认实现为不同的对象返回不同的整数。在此特定示例中,因为我们尚未定义自己的hashCode()方法,所以默认实现将为两个白狗返回两个不同的整数!这违反了合同。
Set中contains()方法的解决方案
class Dog{
String color;

public Dog(String s){
	color = s;
}

//overridden method, has to be exactly the same like the following
public boolean equals(Object obj) {
	if (!(obj instanceof Dog))
		return false;	
	if (obj == this)
		return true;
	return this.color.equals(((Dog) obj).color);
}

public int hashCode(){
	return color.length();//for simplicity reason
}}

最后,开发这么多年我也总结了一套学习Java的资料与面试题,如果你在技术上面想提升自己的话,可以关注我,私信发送领取资料或者在评论区留下自己的联系方式,有时间记得帮我点下转发让跟多的人看到哦。在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章