黑馬程序員-hashCode()的作用

——- android培訓java培訓、期待與您交流! ———-

問題:hashCode()在對象比較時很常用,那麼它的作用究竟是什麼?

1)利用哈希算法,提高了查找效率。
2)hashCode必須在哈希集合中才有用。
3)防止內存泄露。對象不用了,但是它沒有被釋放掉,一直佔用內存。

看下面實例1:

定義已知類ReflectPoint

class ReflectPoint
{
    private int x;
    public int y;
    public String str1 = "ball";
    public String str2 = "basketball";
    public String str3 = "all";
    public ReflectPoint(int x,int y)
    {
        super();
        this.x = x;
        this.y = y;
    }
    public String toString()
    {
        return str1+"......"+str2+"......"+str3+"......";
    }
}
public class ReflectTest2
{
    public static void main(String args[])
    {
        Collection collections = new ArrayList();
        ReflectPoint pt1 = new ReflectPoint(3,3);
        ReflectPoint pt2 = new ReflectPoint(5,5);
        ReflectPoint pt3 = new ReflectPoint(3,3);

        collections.add(pt1);
        collections.add(pt2);
        collections.add(pt3);
        collections.add(pt1);

        System.out.println(collections.size());//打印結果爲4
    }
}

該上述代碼ArrayList爲HashSet看結果又如何?
示例2:

public class ReflectTest2
{
    public static void main(String args[])
    {
        Collection collections = new ArrayList();
        ReflectPoint pt1 = new ReflectPoint(3,3);
        ReflectPoint pt2 = new ReflectPoint(5,5);
        ReflectPoint pt3 = new ReflectPoint(3,3);

        collections.add(pt1);
        collections.add(pt2);
        collections.add(pt3);
        collections.add(pt1);

        System.out.println(collections.size());//打印結果爲3
    }
}

這是因爲ArrayList可以存放相同對象,而HashSet不可存放相同對象。
但是當ReflectPoint覆寫hashCode()和equals()方法後,看結果又如何?
示例3:
定義已知類ReflectPoint

class ReflectPoint
{
    private int x;
    public int y;
    public String str1 = "ball";
    public String str2 = "basketball";
    public String str3 = "all";
    public ReflectPoint(int x,int y)
    {
        super();
        this.x = x;
        this.y = y;
    }

    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime*result + x;
        result = prime*result + y;
        return result;
    }

    public boolean equals(Object obj)
    {
        if(this==obj)
            return true;
        if(obj==null)
            return false;
        if(getClass()!=obj.getClass())
            return false;
        final ReflectPoint other = (ReflectPoint)obj;
        if(x!=other.x)
            return false;
        if(y!=other.y)
            return false;
        return true;
    }
    public String toString()
    {
        return str1+"......"+str2+"......"+str3+"......";
    }
}
public class ReflectTest2
{
    public static void main(String args[])
    {
        Collection collections = new ArrayList();
        ReflectPoint pt1 = new ReflectPoint(3,3);
        ReflectPoint pt2 = new ReflectPoint(5,5);
        ReflectPoint pt3 = new ReflectPoint(3,3);

        collections.add(pt1);
        collections.add(pt2);
        collections.add(pt3);
        collections.add(pt1);

        System.out.println(collections.size());//打印結果爲2
    }
}

由此可見,加上hashCode方法後,如果兩個對象的哈希碼相等,則兩者屬於同一對象,屬於重複,所以打印結果爲2。

注意:

當一個對象被存儲到HashSet集合後,就不能修改這個對象中的那些參與計算哈希值的字段了,否則,對象修改後的哈希值與最初存儲進HashSet集合時的哈希值就不同了,這種情況下,即使在contains方法使用該對象的當前引用作爲的參數去HashSet集合中檢索對象,也將返回找不到對象的結果,這也會導致無法從HashSet集合中單獨刪除當前對象,從而造成內存泄露。

示例:4:
修改上述代碼:

public class ReflectTest2
{
    public static void main(String args[])
    {
        Collection collections = new HashSet();
        ReflectPoint pt1 = new ReflectPoint(3,3);
        ReflectPoint pt2 = new ReflectPoint(5,5);
        ReflectPoint pt3 = new ReflectPoint(3,3);

        collections.add(pt1);
        collections.add(pt2);
        collections.add(pt3);
        collections.add(pt1);

        pt1.y = 7;
        collections.delete(pt1);

        System.out.println(collections.size());//打印爲2
    }
}

此時改變了pt1中屬性y的值,此時pt1的哈希碼變了,因此找不到剛存入時pt1的哈希碼了,因此pt1實際上並未被刪除,如此下去,會出現內存泄露。

當不改變存入的對象的跟哈希碼關聯的屬性時,可以正確的刪除pt1.
示例5:

public class ReflectTest2
{
    public static void main(String args[])
    {
        Collection collections = new HashSet();
        ReflectPoint pt1 = new ReflectPoint(3,3);
        ReflectPoint pt2 = new ReflectPoint(5,5);
        ReflectPoint pt3 = new ReflectPoint(3,3);

        collections.add(pt1);
        collections.add(pt2);
        collections.add(pt3);
        collections.add(pt1);

        collections.delete(pt1);
        System.out.println(collections.size());//打印結果爲1
    }
}

此爲hashCode的用法和作用,希望大家能加深理解。

發佈了32 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章