Java集合總結:

weixin_34293059發表於2016-09-14

概述:儘管已經將java核心程式設計中的集合看了好幾遍了,但是還是感覺心裡沒有低;所以今天特別將集合這塊常見的面試題進行總結,一邊加深自己對java集合的理解;
<1>:談談你對HashMap具體實現的理解:
首先,hashMap是一個鍵值對型別的集合,他的鍵和值都可以為null;
使用hashMap儲存資料時,首先我們鍵會先呼叫它的hashCode方法生成一個hashCode值,然後對這個的hashCode值再進一次移位的運算;

//java中的抖動函式
static  final int hash(Object Key){
    int h;
    if(key== null){
      return null  
    }else{
     return key==null ? 0:((h=h.hashCode) ^ h>>>16)
  }
} 

當然這樣得到的hash值是不能直接作為陣列的索引儲存的;太大的;改進後的hashMap初始容量才是16;所以我們還需要對這個得到的值進行一次模運算:

 static int indexFor(int hash, int length) {
        return hash & (length-1);
   }

得到的結果便是我們想要儲存的bucket的位置;此時如果籃子中沒有值,我們直接將值放進這個bucket中鍵即可;如果有值即產生了我們所謂的hash衝突了;
雜湊表要解決的一個問題就是雜湊值的衝突問題,通常是兩種方法:連結串列法和開放地址法。
連結串列法就是將相同hash值的物件組織成一個連結串列放在hash值對應的槽位;
開放地址法是通過一個探測演算法,當某個槽位已經被佔據的情況下繼續查詢下一個可以使用的槽位。java.util.HashMap採用的連結串列法的方式,連結串列是單向連結串列。形成單連結串列的核心程式碼如下:

void addEntry(int hash, K key, V value, int bucketIndex) {
        if ((size >= threshold) && (null != table[bucketIndex])) {
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }
        createEntry(hash, key, value, bucketIndex);
    }
 void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        size++;
    }

相關文章