资讯专栏INFORMATION COLUMN

Java中的 equals() 和 hashCode() 契约

rainyang / 2192人阅读

摘要:我们使用调试器却发现在中已经存储了这个对象。中和有一个契约如果两个对象相等的话,它们的必须相等但如果两个对象的相等的话,这两个对象不一定相等。的结构能够快速找到一个对象,而不是进行较慢的线性查找。可以看作是数组的数组。

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 == ((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 m = new HashMap();
        m.put(a1, 10);
        m.put(a2, 20);
        System.out.println(m.get(new Apple("green")));
    }
}

这个例子中,一个“绿苹果”的对象成功添加到hashMap中了,但是当我们要取出这个“绿苹果”的时候,却得不到这个对象,程序返回null。我们使用调试器却发现在hashMap中已经存储了这个对象。

2. hashCode()引起的问题

这个问题是因为”hashCode()”方法没有被重写。Java中equals()和hashCode()有一个契约:

如果两个对象相等的话,它们的hash code必须相等;

但如果两个对象的hash code相等的话,这两个对象不一定相等。

Map的结构能够快速找到一个对象,而不是进行较慢的线性查找。使用hash过的键来定位对象分两步。Map可以看作是数组的数组。第一个数组的索引就是对键采用hashCode()计算出来的值,再在这个位置上查找第二个数组,使用键的equals()方法来进行线性查找,直到找到要找的对象。

Object类中的hashCode()对于不同的对象返回不同的整数,所以上面的例子中,不同的对象(即使相同的类型)也返回不同的hash值。

Hash码就像是一个存储空间的序列,不同的东西放在不同的存储空间中。将不同的东西整理放在不同的空间中(而不是堆积在一个空间中)更高效。所以能够均匀的分散hash码是再好不过了。

上面错误的解决方法就是在类中增加hashCode方法。这里我仅仅使用颜色的长度来计算hash码。

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

原文:Java equals() and hashCode() Contract
翻译:ImportNew.com - 唐小娟

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64050.html

相关文章

  • 第3章:抽象数据类型(ADT)面向对象编程(OOP) 3.5 ADTOOP中的等价性

    摘要:抽象函数引发的关系是等价关系。所以当且仅当通过调用抽象数据类型的任何操作不能区分它们时,两个对象是相等的。必须为每个抽象数据类型适当地定义操作。一般来说,在面向对象编程中使用是一种陋习。 大纲 什么是等价性?为什么要讨论等价性?三种等价性的方式==与equals()不可变类型的等价性对象契约可变类型的等价性自动包装和等价性 什么是等价性?为什么要讨论等价性? ADT上的相等操作 ADT...

    Fundebug 评论0 收藏0
  • Java™ 教程(对象排序)

    对象排序 List l可以如下排序。 Collections.sort(l); 如果List包含String元素,它将按字母顺序排序,如果它由Date元素组成,它将按时间顺序排序,这是怎么发生的?String和Date都实现了Comparable接口,Comparable实现为类提供了自然的顺序,允许该类的对象自动排序,下表总结了一些实现Comparable的更重要的Java平台类。 类 自然...

    Chao 评论0 收藏0
  • 第3章:抽象数据类型(ADT)面向对象编程(OOP) 3.2设计规约

    摘要:程序失败时,很难确定错误的位置。它保护客户免受单位工作细节的影响。将前提条件放在中,并将后置条件放入和。涉及可变对象的契约现在取决于每个引用可变对象的每个人的良好行为。设计规约按规约分类比较规约它是如何确定性的。 大纲 1.编程语言中的功能/方法2.规约:便于交流的编程,为什么需要规约 行为等同规约结构:前提条件和后条件测试和验证规约3.设计规约分类规约图表规约质量规约4.总结 编程...

    mozillazg 评论0 收藏0
  • 【码艺杂谈】Java中的相同与不同

    摘要:如果根据方法得到两个对象不相同,那么两个对象的方法的结果不一定不相同,我们可以利用这一点来提高散列表的性能。最后回到文章开头的问题,如何判断两个对象或值是否相同这个问题其实有两方面的含义,一方面是判断的方法,另一方面是判断的效率。 Java中有很多场景需要判断两个对象或者两个值,那么 判断是否相同的依据是什么? 如何判断是否相同呢? 为了解释这个问题,我们从Java语言的根说起,那...

    xingqiba 评论0 收藏0
  • java中的hashCode

    摘要:相关的文章网上很多了写这个主要是按自己的思路进行记录是什么中的实现是一个本地方法生成一个表征当前对象实例的特征值具体的实现根据的实现可能会不同中实际计算的函数的实现如下为时是直接使用的内存地址但默认使用的是的随 hashcode相关的文章网上很多了, 写这个主要是按自己的思路进行记录 hashCode是什么 Object中的hashCode实现是一个本地方法, 生成一个表征当前对象实例...

    cnTomato 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<