Object類學習之二:equals()
阿新 • • 發佈:2020-08-26
先上原始碼
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();