Java中equals()和hashCode()的区别与联系


Java的超类java.lang.Object定义了两个非常重要的方法:
public boolean equals(Object obj)
public int hashCode()
理解这两方法之间的区别联系是非常重要的,特别是当用户自定义的对象被添加到Map中。然而,即使高级开发人员有时无法弄清楚他们应该如何正确使用。在这篇文章中,我会先给大家看一个常见的错误的例子,然后解释如何的equals()和hashCode()之间的区别联系。
1.一个常见的​​错误
请看下面的例子:

import java.util.HashMap;
 
public class Apple {
	private String color;
 
	public Apple(String color) {
		this.color = color;
	}
 
	public boolean equals(Object obj) {
		if (!(obj instanceof Apple))
			return false;	
		if (obj == this)
			return true;
		return this.color.equals(((Apple) obj).color);
	}
 
	public static void main(String[] args) {
		Apple a1 = new Apple("green");
		Apple a2 = new Apple("red");
 
		//hashMap stores apple type and its quantity
		HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
		m.put(a1, 10);
		m.put(a2, 20);
		System.out.println(m.get(new Apple("green")));
	}
}


在这个例子中,一个color属性为“green”的Apple对象被成功地存储在一个HashMap中,但是当Map被要求获取该对象时,结果发现Apple对象没有找到。上面的程序在控制台打印为null。但是,我们可以肯定的是,通过在调试器可以查看到对象确实是存储在HashMap中:

2.hashCode()造成的问题
这个问题是由未重写的方法hashCode()引起的。equals()和hasCode()之间的制约关系是:
1.如果两个对象是相等的,那么它们必须有相同的哈希码。
2.如果两个对象具有相同的哈希码,他们可能相等,可能不相等。
一个Map背后的想法是能够比线性搜索更快地定位到对象。使用散列键定位对象是一个两步的过程。Map内部存储对象是以数组的数组来存储。1.第一个数组的索引是hashCode()值的key。2.定位第二个数组(使用线性搜索找到的)是通过使用equal()来决定对象是否被找到?

hashCode()的默认实现是Object类为不同的对象返回不同的整数。因此,在上面的例子中,不同的对象(即使是相同类型的)具有不同的哈希码。

哈希码的存储就像车库中的序列一样,不同的车(对象)可以被存储在不同的车库中。如果你将不同的车(对象)放在不同的车库中而不是相同的车库中,那么会更有效。所以平均分配的hashCode值是一个很好的做法。(虽然不是这里的要点)

下面的例子是为一个类添加hashCode()方法的简单的解决方案,在这里,我只是用color字符串的长度作示范。

public int hashCode(){
	return this.color.length();	
}

相关文章:

  1. Java hashCode() and equals() Contract for the contains(Object o) Method of Set
  2. HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap
  3. Yet Another “Java Passes By Reference or By Value”?
  4. What does a Java array look like in memory?
原文:

Java equals() and hashCode() Contract

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值