JAVA學習之HashCode,javahashcode

來源:互聯網
上載者:User

JAVA學習之HashCode,javahashcode

public native int hashCode();

返回該對象的雜湊碼值。支援此方法是為了提高雜湊表(例如 java.util.Hashtable 提供的雜湊表)的效能。 

一、HashCode的作用

  我們通常會用equals判斷集合中是否包含一個對象,這種方式需要遍曆集合中每一個元素,然後對他們一一進行equals方法比較。對於少量資料的集合該方式自然可以,但當我們的資料很多例如一萬個,如果還使用這種逐個遍曆的方式顯然不合適。於是有人發明了一種雜湊演算法來提高從集合中尋找元素的效率。這種方式的核心就是將集合分為若干個地區,每個對象可以計算出一個雜湊碼,可以將雜湊碼分組,每組分別對應某個儲存地區,尋找對象時我們先根據對象的雜湊碼來確定該Object Storage Service在某個地區。然後在這個地區內尋找元素。

 

在java中HashSet、HashMap以及HashTable這些散列集合,就是與hashCode方法一起使用。

下面這段代碼是java.util.HashMap的中put方法的具體實現:

 public V put(K key, V value) {        if (table == EMPTY_TABLE) {            inflateTable(threshold);        }        if (key == null)            return putForNullKey(value);        int hash = hash(key);        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;    }

  put方法是用來向HashMap中添加新的元素,從put方法的具體實現可知,會先調用hashCode方法得到該元素的hashCode值,然後查看table中是否存在該hashCode值,如果存在則調用equals方法重新確定是否存在該元素,如果存在,則更新value值,否則將新的元素添加到HashMap中。從這裡可以看出,hashCode方法的存在是為了減少equals方法的調用次數,從而提高程式效率。

二、equals與HashCode

1、equals與HashCode必須一起出現

在put()方法中為什麼判斷HashCode後還要判斷equals?

因為不同的對象可能會產生相同的hashcode值,所以我們不能根據hashcode值判斷兩個對象是否相等。但是可以直接根據hashcode值判斷兩個對象不等,如果兩個對象的hashcode值不等,則必定是兩個不同的對象。如果要判斷兩個對象是否真正相等,必須通過equals方法。

所以我們在重寫equals方法時一定要重寫hashcode方法。因為散列集合在添加資料的時候會先判斷對象的hashCode值,hashcode值不同,他們就會被散列在不同的儲存地區,所以接下來再比較equals的時候已經沒有意義了,這個時候就違背了集合的意義(不允許重複元素的 集合)。

 2、保證集合中的對象的hashcode值不能改變

當一個對象被儲存在散列集合後,就不能修改這個對象中的哪些參與計算雜湊值的欄位了,否則,對象修改後的雜湊值與最初存入集合時的雜湊值不相等了,在這中情況中,及時在contains方法使用該對象的當前應用作為參數去散列集合中檢索對象,也將出現找不到對象的結果,這將會導致無法從散列集合中單獨刪除當前對象,從而照成記憶體溢出。

使用HashSet示範:

package com.jalja.org.base.test;import java.util.HashSet;import java.util.Set;public class Point {    private int x;    private int y;        public Point(int x, int y) {        super();        this.x = x;        this.y = y;    }    public int getX() {        return x;    }    public void setX(int x) {        this.x = x;    }    public int getY() {        return y;    }    public void setY(int y) {        this.y = y;    }        @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + x;        result = prime * result + y;        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Point other = (Point) obj;        if (x != other.x)            return false;        if (y != other.y)            return false;        return true;    }    public static void main(String[] args) {        Point point1=new Point(1,2);        Point point2=new Point(2,3);        Point point3=new Point(3,4);        Set<Point> set=new HashSet<Point>();        set.add(point1);        set.add(point2);        set.add(point3);        System.out.println(set.size());//3        point1.setX(5);//改變 point1的x值        set.remove(point1);//移除 point1        System.out.println(set.size());//3    }}

從結果可以看出 point1已經無法刪除了。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.