java基礎解析系列(十一)---equals、==和hashcode方法

java基礎解析系列(十一)---equals、==和hashcode方法

目錄

==

  • 基本數據類型==比較的是值
類型 字節數
float 4
double 8
byte 1
short 2
int 4
long 8
char 2
boolean
  • 非基本數據類型,也就是引用型變量,==比較的是指向的內存地址

equals

  • Object類的的equals方法內部是用==比較,也就是比較地址
public boolean equals(Object obj) {
        return (this == obj);
    }
  • 而若是不一樣類會重寫equals方法,好比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;
    }

hashcode方法

做用

  • 若是沒有hashcode方法,在往一個set(不容許重複)添加的元素的時候,那麼就得將所有的元素檢查一遍equals,若是有hashcode方法,一個對象的hashcode會映射到一個位置,在這個位置檢查是否存在便可,因此不須要所有檢查。能夠看看hashmap的put方法
public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
 
        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }
  • 從源碼能夠看到,先經過hash值找到在table中的位置,而後再進行查找,這樣就減小了執行equals的次數

equals方法和hashcode方法

  • equals方法返回true,hashcode必定相同
  • equals方法返回flase,hahscoe不必定不一樣

修改了equals方法

  • 前面已經瞭解過,Object的equals返回兩個對象的內存地址是否相同,而Object類的子類常常會重寫equals方法,好比兩個People對象,比較的不是兩個People對象的內存地址,而是比較name,age等屬性,只要name和age相同就認爲是同一個對象
  • 若是隻重寫了equals而不重寫hashcode方法,下面進行測試
public static void main(String[] args) throws Exception {
        HashMap hashMap=new HashMap<Person,Integer>();
        Person p1=new Person("jiajun",18);
        Person p2=new Person("jiajun",18);
        System.out.println("這兩個對象在設置的時候應該是相同的");
        hashMap.put(p1,666);
        System.out.println("那麼按照咱們的設計思路,咱們經過p2應該能夠獲得666");
        System.out.println(hashMap.get(p2));
        System.out.println("但是這時候輸出的倒是null");
}
class Person
{
    String name;
    int age;
    public Person(String name,int age)
    {
        this.name=name;
        this.age=age;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if(this.getClass()!=obj.getClass())
        {
            return false;
        }
        People p = (People)obj;
        return this.name.equals(p.name)
                && this.age == p.age;
    }

}
  • 從實驗結果能夠看出,若是重寫了equals方法而不重寫hashcode方法容易出現問題

Effective java的建議

  • 在程序執行期間,只要equals方法的比較操做用到的信息沒有被修改,那麼對這同一個對象調用屢次,hashCode方法必須始終如一地返回同一個整數
  • 若是兩個對象進行equals比較是相等的,那麼這兩個對象的hashcode方法必須返回相同的整數結果
  • 若是兩個對象進行equals比較是不一樣的,那麼這個兩個對象hahscode方法不必定返回不一樣的整數

我以爲分享是一種精神,分享是個人樂趣所在,不是說我以爲我講得必定是對的,我講得可能不少是不對的,可是我但願我講的東西是我人生的體驗和思考,是給不少人反思,也許給你一秒鐘、半秒鐘,哪怕說一句話有點道理,引起本身心裏的感觸,這就是我最大的價值。(這是我喜歡的一句話,也是我寫博客的初衷)

做者:jiajun 出處: http://www.cnblogs.com/-new/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。若是以爲還有幫助的話,能夠點一下右下角的【推薦】,但願可以持續的爲你們帶來好的技術文章!想跟我一塊兒進步麼?那就【關注】我吧。html

相關文章
相關標籤/搜索