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方法讲解

  • 2017-04-15 09:02
  • 72KB
  • 下载

hashcode和equals的分析

  • 2011-12-09 10:24
  • 76KB
  • 下载

equals和hashCode方法详解

一、初识equals()和hashCode()方法   1、首先需要明确知道的一点是:hashCode()方法和equals()方法是在Object类中就已经定义了的,所以在java中定义...

Object的equals()及hashCode()(

Object的equals()及hashCode() 在某些时候,我们需要判断两个对象是否相等。Java的每个类都继承于Object类。它使用equals()及hashCode()这两个...

解析Java对象的equals()和hashCode()的使用

前言 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况 下,这两个函数是不用考虑的,直接使用它们的默认设计就可以...
  • wkcgy
  • wkcgy
  • 2011-03-11 16:48
  • 416

equals与hashCode方法详解

一、在讲解之前,我们先来看看Java jdk源码里边的一些关于equals方法: 1.这是Java基类Object里边的equals和hashCode方法,特殊的是这里比较的是两个对象是否相等;pu...

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

java.lang.Object类中有两个非常重要的方法: public boolean equals(Object obj) public int hashCode() 理解这两个方法非常...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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