把Hashmap的方法

时间:2014-08-04 07:12:58

标签: java collections hashmap

我看到在HashMap类的put方法的实现中,使用int i = indexFor(hash, table.length);获取表桶,然后在该桶中添加一个条目 - ' i'如果哈希码和密钥不相等。如果它们相等,则替换旧值。

  • 如何使用密钥找到合适的存储桶?如果存储桶不存在怎么办?
  • 如何评估是否需要将其添加到同一个存储桶或不同的存储桶中?
  • 当哈希码相同且密钥不同时会发生什么?如果哈希码相同,那么该条目应该在同一个桶中,但我没有在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;
}


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++;
    }

2 个答案:

答案 0 :(得分:0)

有些时候出于锻炼目的,我已经编写了哈希映射的简单实现(code)我认为阅读你可以得到你的问题的答案。

测试您可以找到here

的实现

利用列表的另一个实现,您可以找到here

答案 1 :(得分:0)

返回indexOf()方法永远不会超过数组大小。 检查HashTable实现,它不像HashMap,但你会得到关于基本散列的想法。

假设您有4个MyClass对象。其哈希码值分别为11,12,13,14。 并且您的默认hashmap大小为10。 那么索引就像那样 -

     index =   hashcode % table.length; 
                     1 =      11     %  10 ;
                     2 =      12     %  10 ;
                     3 =      13     %  10 ;

1,2,3是索引值,您的条目存储在数组中。

如果你的类哈希码是21,那么它的索引将是21%10 = 1;

索引1已经有一个Entry对象,因此它将存储为LinkedList。