回覆列表
  • 1 # 淘寶客老妖

    hash是Object的一個方法 Object.hashCode() ; 返回值是int型別

    1、Hash值有什麼用?

    HashMap、HashTable、HashSet,所以涉及到使用Hash值進行最佳化儲存的地方,都會用到HashCode。HashCode是Key,這種計算為提高計算的效能。想想看,一般來說,陣列算是比較快的集合類了吧,直接用index定位元素,簡直就是O(1)的級別。但是新增元素就不這麼樂觀了。但是使用hash類的集合,新增元素,移動的元素少,隻影響一小塊,並且查詢元素,由於hash值已經進行了定位分組,所以也會大大縮小涉及面,快速定位。

    2、Hash值應該符合什麼原則?

    A、等冪性。不管執行多少次獲取Hash值的操作,只要物件不變,那麼Hash值是固定的。如果第一次取跟第N次取不一樣,那就用起來很麻煩,需要記錄當前是第幾次操作,這種需要記錄狀態的事情,可不是什麼好事。

    B、對等性。若兩個物件equal方法返回為true,則其hash值也應該是一樣的。舉例說明:若你將objA作為key存入HashMap中,然後new了一個objB。在你看來objB和objA是一個東西(因為他們equal),但是使用objB到hashMap中卻取不出來東西。

    C、互異性。若兩個物件equal方法返回為false,則其hash值最好也是不同的,但這個不是必須的,只是這樣做會提高hash類操作的效能(碰撞機率低)。

    3、Hash值應該怎麼計算?

    A、簡單計算就是組成成員的hash值直接相加即可。比如ObjectA有三個屬性,propA、propB和propC,最直接的計算方式就是propA.hashcode+propB.hashcode+propC.hashcode。

    B、但是如果遇到有順序相關的怎麼辦?比如String型別是由char陣列組成,並且這些陣列是有順序的。如果使用第一種計算方法,則“ABCD”和“BCDA”就會產生同樣的hashCode,那麼怎麼辦呢?最直接想到的辦法就是加權,不同的index加不同的權值,這個權值的確定最直接的方法就是某個常數值的幾次冪。比如為String的計算hash值為K^0*A.hashCode+K^1*B.hashCode+K^2*C.hashCode+K^3*D.hashCode。K的選擇也有說法,最好不要是偶數,因為偶數的相乘會造成資訊的丟失(乘以2就是左移1位,一旦溢位就會造成資訊的丟失,這種計算會造成溢位後的值與某個看似不相關的數值得到的結果是一樣的),所以最好是奇數,在這一點上比較推薦使用7,因為7=8-1=2^3-1,這樣計算的時候,直接左移幾位再進行一次普通的加減法即可(Java中常用的是31(32-1=2^5-1))

  • 中秋節和大豐收的關聯?
  • 30平米的房間按多大的空調?