equals 和 ==, equals 和 hashcode

原创 2016年05月31日 02:39:10

equals 和 ==, equals 和 hashcode

回顾下 Java 的一些基础知识

测试类

public class Person {
    public String name;
    public int age;

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

1. equals 和 ==

  1. equals 默认就是 == ,比较引用内存地址
  2. String、Integer 等类重写了 equals 方法, 比较值

Object.equals 源码

public boolean equals(Object obj) {
    return (this == obj);
}

String.equals 源码

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;
}

测试

 @Test
public void StringEquals() {
    String a = "123";
    String b = new String("123");
    assertEquals(a, b);
    assertTrue(a.equals(b));
    assertFalse(a == b); // 涉及到常量池
}

常量池就不细抠了,网上太多了。

重写 equlas 方法

那么对于引用类型,默认 equals 也是 ==。但是对于业务来说,通常内部值相等,就算相同了,可以重写 equals 方法,使之可以进行比较。

重写 Person.equals

@Override
public boolean equals(Object o) {
    // 相同的引用地址
    if (this == o) return true;

    //  不是本类的实例
    if (o == null || getClass() != o.getClass()) return false;

    Person person = (Person) o;
    // 比较具体值
    return age == person.age && name.equals(person.name);

}

测试

// 对于对象,重写 equals 使之可以进行值的比较
@Test
public void ObjectEquals() {
    Person a = new Person("hehe", 10);
    Person b = new Person("hehe", 10);
    // 默认比较引用地址 false
//        assertNotEquals(a, b);
    assertEquals(a, b);
}

2. equals 和 hashcode

重写 equals 为什么要重写 hashcode 方法?这是初学 Java 时经常看到的问题。

来看下 hashcode 方法的注释,之前并没有自己看过,都是各种文章撸过去的

 /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * <p>
     * The general contract of {@code hashCode} is:
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code hashCode} method on each of the
     *     two objects must produce distinct integer results.  However, the
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>
     * <p>
     * As much as is reasonably practical, the hashCode method defined by
     * class {@code Object} does return distinct integers for distinct
     * objects. (This is typically implemented by converting the internal
     * address of the object into an integer, but this implementation
     * technique is not required by the
     * Java&trade; programming language.)
     *
     * @return  a hash code value for this object.
     * @see     java.lang.Object#equals(java.lang.Object)
     * @see     java.lang.System#identityHashCode
     */
    public native int hashCode();

简单的说就是主要用于 HashMap,当然也涉及到 LinkedHashMap、HashSet等

约定一下
1. 程序执行过程中,对同一对象多次调用 hashcode 应当返回一直,前提是将对象进行 equals 比较时所用的信息没有被修改。
2. 如果俩对象 equals, 则 hashCode 也应该相等
3. 如果俩对象不 equals,则不要求 hashcode 相等。但程序员们应当知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。

所以其实刚才的问题就不是问题了,哪那么多道道,要求怎么来就怎么来呗,重写 equals 的时候顺带重写了 hashcode 方法,用以保证集合中元素唯一。

集合先判断 hashcode 是否相同,不同则为不同对象。但对象的 hashcode 默认是不同的(返回的实际上是该对象在jvm的堆上的内存地址,而不同对象的内存地址肯定不同),所以重写 equals 判断俩对象相同后集合却不承认,所以要重写 hashcode

如果 hashcode 相同(目测通常是人为因素),再判断 equals,不同则为不同对象。反之为相同对象。

版权声明:本文为博主原创文章,未经博主允许请火速转载。

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

equals和hashCode重写技巧
  • zzg1229059735
  • zzg1229059735
  • 2016年05月25日 15:36
  • 6388

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

equals()是判读两个Set是否相等[前提是equals()在类中被覆盖]。==决定引用值是否指向同一对象。 1、当向集合set中增加对象时,首先计算要增加对象的hashCode码,根据该值来得到...
  • lishehe
  • lishehe
  • 2014年01月28日 11:43
  • 5502

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

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

equals与hashCode方法讲解

  • 2017年04月15日 09:02
  • 72KB
  • 下载

hashcode和equals的分析

  • 2011年12月09日 10:24
  • 76KB
  • 下载

java 举例分析 equals hashcode 基本类型与基本对象的比较 shot与Short int与Integer long与Long

  • 2015年07月06日 14:45
  • 11KB
  • 下载

关于hashCode()和equals()的本质区别和联系

  • 2008年04月03日 17:16
  • 37KB
  • 下载

==、equals以及hashCode的理解及相关面试题

项目中经常用到==以及equals,但是他们直接的区别好多都是在面试的时候才会被问到,想到这问题的时候代码中可能会想起部分用到==与equals的地方,比如判断boolean用==的场景以及字符串用e...
  • weixin_41098980
  • weixin_41098980
  • 2018年01月17日 14:40
  • 1

两个对象用equals方法比较为true,它们的Hashcode值相同吗?

两个对象用equals方法比较为true,它们的Hashcode值相同吗?        答:不一定相同。正常情况下,因为equals()方法比较的就是对象在内存中的值,如果值相同,那么Hash...
  • chwshuang
  • chwshuang
  • 2015年07月18日 17:17
  • 4840

建立一个对象模型的时候,为什么要重写hashCode与equals方法

为了阐明其作用,我们先来假设有如下一个Person类。 [java] view plain copy class Person {       p...
  • m0_37443464
  • m0_37443464
  • 2017年06月20日 13:10
  • 111
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:equals 和 ==, equals 和 hashcode
举报原因:
原因补充:

(最多只允许输入30个字)