equals()和hashCode()之间的关系

简介:

在Java的基类java.lang.Object中有两个非常重要的方法:

public boolean equals(Object obj)
public int hashCode()

对这两个方法的理解非常重要,特别是当用户自己定义对象,并将其存入到Map中的时候;

然而,即便是高级开发人员,有时候也搞不清楚如何正确的使用它们;

在这篇文章,我首先会展示一种常见的错误示例,然后解释如何正确的使用这两个方法;

常犯的错误

如下代码是常见的错误使用示例:

复制代码
package simplejava;

import java.util.HashMap;

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 class Q9 {
    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")));
    }
}
复制代码

在这个例子中,一个绿色苹果对象成功存入到hashMap中,但是当我们要取出来的时候,得到的却是null;然而通过调试程序,我们确实看到了hashmap中的绿苹果对象;

错误原因-hashcode()方法导致

之所以出现这个错误是因为没有重写hashCode()方法导致的。

hashCode()和equals()的关系是这样的:

如果两个对象相等(equal),它们的hashcode一定相同;

如果两个对象有相同的hashcode,它们不一定相等(equal);

之所以这样设计是为了在Map中更快的查找到对象(相对于线性搜索);

一般Map都设计成数组+链表的结构,使用hashcode去查找对象需要两个步骤,首先使用hashcode定位数组下标索引,然后遍历该数组元素对应的链表,找到equals的元素;

Object默认的hashcode实现对于不同的对象会返回不同的值,因此,在上面那个例子中,不同的对象(即使同一个类型)有着不同的hashcode;

值的散列就像在车库储存货物,不同的货物能被存放到不同的车库。比较有效查找货物办法是将不同的货物存到不同的车库中,而不是同一个车库;

所以将hash值尽可能的分散是一个比较好的策略;

关于这个例子,解决办法是添加hashcode方法,这里我将使用颜色的长度作为示范,如下代码:

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

 本文转自风一样的码农博客园博客,原文链接:http://www.cnblogs.com/chenpi/p/5489494.html,如需转载请自行联系原作者

相关文章
|
2月前
|
存储 Java
两个对象的 hashCode()相同,则 equals()
当两个对象的 `hashCode()` 方法返回值相同时,这两个对象的 `equals()` 方法不一定返回 `true`。`hashCode()` 相同仅表示两对象可能相等,需进一步通过 `equals()` 方法验证对象是否真正相等。
36 7
|
5月前
|
存储 Java
|
6月前
|
Java 容器
equals与hashcode的区别与联系
equals与hashcode的区别与联系
|
7月前
|
索引
foreach、for in和for of之间区别?
foreach、for in和for of之间区别?
318 0
|
8月前
|
JavaScript 前端开发 索引
foreach、for in 和for of之间的区别
foreach、for in 和for of之间的区别
63 6
|
8月前
equals方法中变量在前和在后的区别
equals方法中变量在前和在后的区别
158 0
|
算法 Java 索引
equals方法和hashCode方法之间的那些事(1.1)
equals方法和hashCode方法之间的那些事(1.1)
|
索引
9. 说说hashCode() 和 equals() 之间的关系?
9. 说说hashCode() 和 equals() 之间的关系?
79 0
9. 说说hashCode() 和 equals() 之间的关系?
|
存储 缓存 Java
深入理解= = 、equals()与hashcode()的关系
理解= = 、equals()与hashcode()的关系
116 0
深入理解= = 、equals()与hashcode()的关系
|
算法 安全 Java
@EqualsAndHashCode - 相等更简单:从对象的字段生成hashCode和equals实现
@EqualsAndHashCode - 相等更简单:从对象的字段生成hashCode和equals实现
729 0