关闭

hashCode和equals

13390人阅读 评论(0) 收藏 举报
分类:
最近在复习的时候,又重新的理解了下equals()和hashCode().
equals()用于判断两个对象是否相等,这是大家公认的。
hashCode()被设计是用来使得哈希容器能高效的工作。

为什么这么说?在java中,有一些哈希容器,比如Hashtable,HashMap等等。当我们调用这些类的诸如get(Object obj)方法时,容器的内部肯定需要判断一下当前对象obj在容器中是否存在,以便进行后续的操作。判断是够存在,肯定是要比较两个对象是否相等,我们"应该"要使用equals()才是正确的。

但是如果哈希容器中的元素有很多的时候,使用equals()必然会很慢。这个时候我们想到一种替代方案就是hashCode()。hashCode()返回一个int类型,比较起来要快很多。但这也造成了一个问题,就是一个判定两个对象事实上存在两个标准?当然不是这样的,正如在文章开头所说,hashCode()被设计用来使得哈希容器中能高效的工作。也只有在哈希容器中,才使用hashCode()来进行比较对象是否相等,而且还是弱的比较。

当我们调用哈希容器的get(Object obj)方法时,他会首先查看当前容器中是够存在相同的哈希值,如果不存在,那么返回null。如果存在,再调用当前对象的equals()方法比较一下看哈希处的对象是否和要查找的对象为相同的对象,如果不是,那么返回null。如果是,说明当前哈希容器存在相应的值,返回该哈希处的对象。

这样hashCode()方法就提高了哈希容器的效率,这就是hashCode()存在的意义。我们可以把hashCode()相等看成是两个对象相等的必要非充分条件,equals()相等才是充分条件。因此,在自定义一个类的时候,我们必须要同时重写equals()和hashCode(),并且必须保证:
1 如果两个对象的equals()相等,那么他们的hashCode()必定相等。
2 如果两个对象的hashCode()不相等,那么他们的equals()必定不等。

<pre name="code" class="java">import java.util.HashMap;

public class Demo {
    public static void main(String[] args) throws Exception{
        Person person=new Person("xyz",22);
        HashMap<Person,Integer> hashMap=new HashMap<Person,Integer>();
        hashMap.put(person, 1);
        System.out.println(hashMap.get(new Person("xyz",22)));
    }
}
class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;

        if (age != person.age) return false;
        return name != null ? name.equals(person.name) : person.name == null;

    }

//    @Override
//    public int hashCode() {
//        int result = name != null ? name.hashCode() : 0;
//        result = 31 * result + age;
//        return result;
//    }
}

上面的代码注释掉hashCode()前后的运行结果不同,当注释掉hashCode()的时候,person和后来新建的Person虽然equals是同一对象,但HashMap容器内部比较hashCode()的时候会认为他们是不同元素。

因此,牢记一点,当我们重写equals()方法时候一定要重写hashCode()方法。下面我们来看看String类的equals方法和hashCode方法:
 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
 public int hashCode() {
        int h = hash;//默认是0
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;//String的哈希值由组成该String的字符串的ASCII值根据相应的规则加和
    }
0
0
查看评论

Java中==和equals的区别,equals和hashCode的区别

==是运算符,用于比较两个变量是否相等。 equals,是Objec类的方法,用于比较两个对象是否相等,默认Object类的equals方法是比较两个对象的地址,跟==的结果一样。Object的equals方法如下: public boolean equals(Object obj) { ...
  • tiantiandjava
  • tiantiandjava
  • 2015-07-21 17:01
  • 19789

如何正确的重写equals() 和 hashCode()方法

equals和hashCode重写技巧
  • zzg1229059735
  • zzg1229059735
  • 2016-05-25 15:36
  • 7323

从一道面试题彻底搞懂hashCode与equals的作用与区别及应当注意的细节

从一道面试题彻底搞懂hashCode与equals的作用与区别
  • lijiecao0226
  • lijiecao0226
  • 2014-04-28 14:24
  • 8986

Java中的equals和hashCode方法详解

Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用。 equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类...
  • jiangwei0910410003
  • jiangwei0910410003
  • 2014-04-01 16:15
  • 54076

"=="、equals和hashCode有什么区别

1)“==”运算符用来比较两个变量的值是否相等。也就是说,该运算符用于比较变量对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能使用“==”运算符。 具体而言,如果两个变量是基本数据类型,可以直接使用“==”运算符来比较其对应的值是否相等。如果一个变量指向的数据是...
  • Dove_Knowledge
  • Dove_Knowledge
  • 2017-04-30 19:29
  • 544

equals和HashCode深入理解以及Hash算法原理

equals()和HashCode()深入理解以及Hash算法原理(带源码分析)
  • qq_21688757
  • qq_21688757
  • 2016-11-07 16:57
  • 4064

HashMap中的equals和hashCode

Java的Object对象有9个方法,其中的equals()和hashCode()在hashMap的实现里面起着比较重要的作用,我在研究hashMap的源码时就遇到了它们俩,此篇博文主要是为了记录它们之间的相爱相杀。为了说明它们的关系,我们需要HashMap的背景知识。HashMap的存储方式Has...
  • qiuych3
  • qiuych3
  • 2016-05-06 21:26
  • 1490

Java学习从菜鸟变大鸟之一 hashCode()和equals()的本质区别和联系

equals()是判读两个Set是否相等[前提是equals()在类中被覆盖]。==决定引用值是否指向同一对象。 1、当向集合set中增加对象时,首先计算要增加对象的hashCode码,根据该值来得到一个位置来存放当前的对象,当在该位置没有一个对象存在的话,那么集合set认为该对象在集合中不存在,直...
  • lishehe
  • lishehe
  • 2014-01-28 11:43
  • 5709

Java中==、equals()和hashCode()的比较分析

在Java语言中,==、equals()、hashCode()这三个方法都和对象的比较有关,
  • taohuaxinmu123
  • taohuaxinmu123
  • 2014-06-17 10:10
  • 2373

Java-正确使用equals和hashCode方法

基本摘抄自Java 中正确使用 hashCode 和 equals 方法 hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。1.equalsequals要遵守的通用约定(equals方法实现了等价关系): 1)自反性...
  • qing0706
  • qing0706
  • 2016-01-27 14:09
  • 1871
    个人资料
    • 访问:151024次
    • 积分:1776
    • 等级:
    • 排名:千里之外
    • 原创:138篇
    • 转载:11篇
    • 译文:0篇
    • 评论:39条
    最新评论