1. 程式人生 > >【Java基礎】equals和hashcode

【Java基礎】equals和hashcode

一、equals

equals是Object類的其中一個方法,預設的實現方法為

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

可以看到,預設方法僅僅是判斷是否為同一物件。因為各個類都是繼承自Object類,所以各個類可以根據需要自己重寫equals方法,如String類等。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;
    }

不僅僅看是否為同一物件,還會比較物件中儲存內容是否相同。

經常被討論到的就是equals的幾個特性:自反性、對稱性、傳遞性、一致性。這些特性就不展開了,網上到處都有,也很好理解。

所以兩個物件呼叫equals結果返回的是true,則一定是相等的,可信的。

二、hashcode

hashcode也是Object類中的一個方法,

public native int hashCode();

hashcode是一個native方法,Object沒有給出具體實現。

hashcode可以產生物件的一個識別碼,用來和別的物件進行區分,但是它不如equals比較的全面和可靠。比如比較兩個人是否為同一個人,hashcode即產生每個人的識別碼,如出生日期,兩個人的出生日期相等但不一定就是同一個人,equals不僅要比較出生日期,還要比較姓名等別的資訊。

那既然如此,為什麼不都用equals來比較,還存在一個hashcode方法呢?

1、hashcode方法雖然不如equals比較的全面和可靠,但是它可以反向的區分出兩個物件不相等:兩個物件如果相等,則hashcode一定相等;如果hashcode不相等,則兩個物件一定不相等。

2、從String類重寫的equals方法可以看出,equals方法比較太繁瑣,沒有hashcode便捷。

所以可以採用先hashcode判斷一輪,hashcode相等,再用equals判斷,equals相等才是真正的相等;hashcode不相等,則一定不相等,就不用equals再判斷了,提高了效率。容器類如HashSet、HashMap等就是這麼實現的。

正因為hashcode和equals配合使用,所以重寫equals方法的同時要記得重寫hashcode方法,不然就可能達不到上面所說的比較效果。