面试

==、hashCode、equals的区别

2018-03-06  本文已影响12人  yyg

作者:http://blog.csdn.net/justloveyou_
原链接:http://blog.csdn.net/justloveyou_/article/details/52464440

一、概述

1、概念


二、关系操作符 ==

1、操作数的值


    String str1;

这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。 而通过 new 来产生一个对象,并将这个对象和str1进行绑定:

str1= new String("hello");

那么 str1 就指向了这个对象,此时引用变量str1中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串”hello”。这里面的引用和 C/C++ 中的指针很类似。


2、小结

因此,对于关系操作符 ==:


三、equals方法

1、来源
  equals方法是基类Object中的实例方法,因此对所有继承于Object的类都会有该方法。

在 Object 中的声明:

    public boolean equals(Object obj) {}

2、equals方法的作用
 初衷 : 判断两个对象的** content **是否相同

为了更直观地理解equals方法的作用,我们先看Object类中equals方法的实现。

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

很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。

但我们都知道,下面代码输出为 true:

public class Main {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");

        System.out.println(str1.equals(str2));
    }
}

原来是 String 类重写了 equals 方法:

public boolean equals(Object anObject) {   // 方法签名与 Object类 中的一致
    if (this == anObject) {     // 先判断引用是否相同(是否为同一对象),
        return true;
    }
    if (anObject instanceof String) {   // 再判断类型是否一致,
        // 最后判断内容是否一致.
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
}

即对于诸如“字符串比较时用的什么方法,内部实现如何?”之类问题的回答即为:

使用equals方法,内部实现分为三个步骤:

Java 中所有内置的类的 equals 方法的实现步骤均是如此,特别是诸如 Integer,Double 等包装器类。


3、equals 重写原则

对象内容的比较才是设计equals()的真正目的,Java语言对equals()的要求如下,这些要求是重写该方法时必须遵循的:


4、小结
 因此,对于 equals 方法:


四、hashCode 方法

1、hashCode 的来源
  hashCode 方法是基类Object中的 实例native方法,因此对所有继承于Object的类都会有该方法。

在 Object类 中的声明(native方法暗示这些方法是有实现体的,但并不提供实现体,因为其实现体是由非java语言在外面实现的):

     public native int hashCode();

2、哈希相关概念
 我们首先来了解一下哈希表:


3、hashCode 简述
 在 Java 中,由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数。(这是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧)。

hashCode 的常规协定是:


4、equals 与 hashCode

前提: 谈到hashCode就不得不说equals方法,二者均是Object类里的方法。由于Object类是所有类的基类,所以一切类里都可以重写这两个方法。


5、实现例证

hashCode()在object类中定义如下:

public native int hashCode();

说明是一个本地方法,它的实现是根据本地机器相关的。

String 类是这样重写它的:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];     //成员变量1

    /** The offset is the first index of the storage that is used. */
    private final int offset;      //成员变量2

    /** The count is the number of characters in the String. */
    private final int count;       //成员变量3

   /** Cache the hash code for the string */
    private int hash; // Default to 0    //非成员变量

    public int hashCode() {
    int h = hash;
        int len = count;         //用到成员变量3
    if (h == 0 && len > 0) {
        int off = offset;         //用到成员变量2
        char val[] = value;       //用到成员变量1
            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];       //递推公式
            }
            hash = h;
        }
        return h;
    }
}

对程序的解释:h = s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],由此可以看出,对象的hash地址不一定是实际的内存地址。


五、小结

上一篇下一篇

猜你喜欢

热点阅读