1. 程式人生 > 實用技巧 >Object類學習之二:equals()

Object類學習之二:equals()

先上原始碼

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

???????????????????????????????????

第一次看的我滿腦子都是問號

所以,這不還是==嗎?

在以前學到的,如果==比較的是八大基本型別,==就是比較數值的大小,如果是引用型別,那麼就是比較的兩個引用變數裡儲存的那個值是不是相同,我們知道那個值就是物件在堆中的地址(繞來繞去,還不是一樣),也就是說比較的兩個引用變數是否指向同一個堆中的物件

所以,這個equals()繞來繞去,內部還不是用 ==實現的,所以根本沒區別,為什麼要給這麼個雞肋?

為了給Object的子類重寫

package com.xyf.javaSE2;

/**
 * @author xyf
 * @create 2020-08-25-21:27
 */
public class Demo01 {
    public static void main(String[] args) {
        String s1=new String("xyf");
        String s2=new String("xyf");
        //String s3=new String("lwy");
        String s3="xyf";
        String s4
="xyf"; System.out.println(s1==s2); System.out.println("=================="); System.out.println(s1.equals(s2)); System.out.println("===================="); System.out.println(s3==s4); System.out.println("============="); System.out.println(s3.equals(s4)); } }

輸出:

false
==================
true
====================
true //這裡也可知道,當使用String string = “”給字串初始化時,這個變數儲存在棧裡
=============
true

我們看到了,s1.equals(s2)返回的值是true,說明啊,這裡呼叫的不是原始Object類裡的equals()方法

我們開啟String類的原始碼

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

果然,String類裡重寫了equals()方法,所以s1.equals(s2)返回為true

補充一點:

為什麼重寫了equals()方法,一定要重寫hashCode()方法?

再看看String類裡是不是重寫了hashCode()?

果然是有的

    public int hashCode() {
        int h = hash;
        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類裡果然是有重寫hashCode()的

/**
     * Indicates whether some other object is "equal to" this one.//顯示某一個其他的物件是不是與當前物件“相等”
     * <p>
     * The {@code equals} method implements an equivalence relation
     * on non-null object references:           //
     * <ul>
     * <li>It is <i>reflexive</i>: for any non-null reference value//自反性
     *     {@code x}, {@code x.equals(x)} should return
     *     {@code true}.//對於任何非空物件 x.equals(x)都應當返回true
     * <li>It is <i>symmetric</i>: for any non-null reference values//對稱性
     *     {@code x} and {@code y}, {@code x.equals(y)}
     *     should return {@code true} if and only if
     *     {@code y.equals(x)} returns {@code true}.//當且僅當 y.equals(x)返回true時,x.equals(y)返回true
     * <li>It is <i>transitive</i>: for any non-null reference values//傳導性
     *     {@code x}, {@code y}, and {@code z}, if
     *     {@code x.equals(y)} returns {@code true} and
     *     {@code y.equals(z)} returns {@code true}, then
     *     {@code x.equals(z)} should return {@code true}.//如果x.equals(y)返回true,y.equals(z)返回true,那麼x.equals(z)也應該返回true
     * <li>It is <i>consistent</i>: for any non-null reference values//一致性
     *     {@code x} and {@code y}, multiple invocations of
     *     {@code x.equals(y)} consistently return {@code true}
     *     or consistently return {@code false}, provided no
     *     information used in {@code equals} comparisons on the
     *     objects is modified.
     * <li>For any non-null reference value {@code x},
     *     {@code x.equals(null)} should return {@code false}.//對於任何物件x x.equals(null)返回false
     * </ul>
     * <p>
     * The {@code equals} method for class {@code Object} implements
     * the most discriminating possible equivalence relation on objects;
     * that is, for any non-null reference values {@code x} and
     * {@code y}, this method returns {@code true} if and only
     * if {@code x} and {@code y} refer to the same object
     * ({@code x == y} has the value {@code true}).    //當且僅當引用變數x與引用變數y指向同一個物件時,x==y返回true
     * <p>
     * Note that it is generally necessary to override the {@code hashCode}
     * method whenever this method is overridden, so as to maintain the
     * general contract for the {@code hashCode} method, which states
     * that equal objects must have equal hash codes.//注意不管何時重寫了本方法,一定要重寫hashCode()方法,以此來保證hashCode()對於相等的物件返回相等的雜湊碼
     *
     * @param   obj   the reference object with which to compare.
     * @return  {@code true} if this object is the same as the obj
     *          argument; {@code false} otherwise.
     * @see     #hashCode()
*
@see java.util.HashMap */

我們再來看看hashCode()的註釋,看看原始碼的作者是如何描述原始hashCode()方法的

The general contract of {@code hashCode} is:
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during     //只要用於比較的資訊沒有改變,不管被呼叫幾次,同一個物件的hashcode永遠保持不變
     *     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)} //通過 equals(Object)方法比較為相同的兩個物件,那麼hashcode也應當相同
     *     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      // 如果兩個物件,用Object原始類裡的初始equals()返回false時,並不要求其hashcode也不同
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}//但是,如果兩個不相等的物件有兩個hashcode,會提高hashtable的效率
     *     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>

通過註釋我們就明白了,為了讓通過equals()方法比較相等的兩個物件hashcode也相同,就必須重寫hashCode();