NET(C#):GetHashCode不需要太復雜 轉


我覺得簡而言之GetHashCode的作用就是:盡量用最快的時間對對象進行初步判斷。當然這里時間的快慢和判斷的深度沒有具體要求,只要沒有走極端就可以(比如太費時間,或者判斷深度太淺)。因此沒必要吧GetHashCode搞得太復雜!

 

還有人錯誤的認為字典的存儲是完全靠GetHashCode的結果,顯然這是不對的,GetHashCode僅返回一個int怎能勝任所有結果呢?

 

 

來看這個例子,這樣一個類,他的GetHashCode返回整數數據的余2的結果。(僅為做示例,很顯然這個GetHashCode的執行很有效率但是比較深度也太差了)

    classa

    {

        publicint Id { get; privateset; }

        public a(int i)

        {

            Id = i;

        }

 

        publicoverridebool Equals(object obj)

        {

            Console.WriteLine("Equals");

            if (obj ==null|| GetType() != obj.GetType())

            {

                returnfalse;

            }

 

            return Id == ((a)obj).Id;

        }

 

        //返回余2的結果

        publicoverrideint GetHashCode()

        {

            Console.WriteLine("GetHashCode");

            return Id %2;

        }

    }

 

接着執行代碼:

            var o1 =newa(1); //GetHashCode返回1

            var o2 =newa(2); //GetHashCode返回0

            var o3 =newa(3); //GetHashCode返回1

 

            var dic =newDictionary<a, object>();

            dic.Add(o1, 123);

            Console.WriteLine("分隔符");

            Console.WriteLine(dic.ContainsKey(o2));

            Console.WriteLine("分隔符");

            Console.WriteLine(dic.ContainsKey(o3));

 

 

程序輸出:

GetHashCode

分隔符

GetHashCode

False

分隔符

GetHashCode

Equals

False

 

可 以看到,當GetHashCode可以直接分辨出不相等時,Equals就沒必要調用了,而當GetHashCode返回相同結果時,Equals方法會 被調用從而確保判斷對象是否真的相等。所以,還是那句話:GetHashCode沒必要一定把對象分辨得很清楚(況且它也不可能,一個int不可能代表所 有的可能出現的值),有Equals在后面做保障。GetHashCode僅需要對對象進行快速判斷。

 

最后你可能有些疑惑為什么不直接用Equals非得搞個GetHashCode在前面先判斷一下?這個由於Equals方法比必須把兩個對象搞清楚是等於 還是不等於,所以可能效率不是最優的(況且Object.Equals通常包含類型的轉換,這個可以參考IEquatable或 IEqualityComparer,他們支持泛型),而GetHashCode不需要絕對弄清楚是否相等所以可以優化下效率。舉個最簡單的例子,比較兩 個人是不是完全一樣(一樣的話代表是他的克隆人),Equals會一個細胞接一個細胞得比較,而GetHashCode可以通過判斷性別,長相,聲音…… 快速得進行判斷。所以先用GetHashCode會很快的判斷出許多不同的人,當然如果GetHashCode返回True(遇到了雙胞胎),再用 Equals進行徹底的比較。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM