简体   繁体   English

Hashtable和hashmap的区别

[英]Difference between Hashtable and hashmap

I'm doing the two sum question but I want to use hashtable instead of hashmap.我正在做两个求和的问题,但我想使用哈希表而不是 hashmap。 When I put the same nums into both hashtable and hashmap.当我将相同的数字放入哈希表和 hashmap 时。 I find out the positions of nums and index in hashtable and hashmap are different.我发现哈希表和 hashmap 中 nums 和 index 的位置不同。 And It seems like hashmap store nums in order according to its bits and hashtable store randomly.并且似乎 hashmap 根据其位和哈希表存储随机存储 nums。 Maybe the difference is because of the hash function.也许差异是因为 hash function。 I don't know if I'm right.我不知道我是否正确。 Can someone explain this to me?谁可以给我解释一下这个? Thank you: Here's hashmap code and output:谢谢:这是 hashmap 代码和输出:

int[] nums = {2, 7, 11, 15,9,1,13};

int target = 9;

int[] result;

Map<Integer, Integer> map = new HashMap<>();

for (int i = 0; i < nums.length; i++) {

    map.put(nums[i], i);
}

System.out.println(map);


if (map.containsKey(target)) {

    System.out.println(map.get(target));
}

Output: Output:

{1=5,2=0,7=1,9=4,11=2,13=6,15=3}

 4

Here's hashtable code and output:这是哈希表代码和 output:

int[] nums = {2, 7, 11, 15,9,1,13};    


int target = 9;    

int[] result;    

Hashtable<Integer, Integer> table = new Hashtable<>();    

for (int i = 0; i < nums.length; i++) {    

    table.put(nums[i], i);} 

System.out.println(table);    


if (table.containsKey(target)) {   
 

System.out.println(table.get(target));}

output: output:

{9=4,7=1,15=3,13=6,2=0,1=5,11=2}
4

The difference comes due to the implementation of put method in both classes.不同之处在于两个类中都实现了 put 方法。 Below are my observations as per JDK 8.以下是我对 JDK 8 的观察。

Hashtable哈希表

Hashtable does bit masking with the help of bitwise AND & then calculate the storage index. Hashtable 在按位 AND 的帮助下进行位掩码,然后计算存储索引。 FYR the method implementation is as follows: FYR方法实现如下:

public synchronized V put(K key, V value) {
    // Make sure the value is not null
    if (value == null) {
        throw new NullPointerException();
    }

    // Makes sure the key is not already in the hashtable.
    Entry<?,?> tab[] = table;
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length;
    @SuppressWarnings("unchecked")
    Entry<K,V> entry = (Entry<K,V>)tab[index];
    for(; entry != null ; entry = entry.next) {
        if ((entry.hash == hash) && entry.key.equals(key)) {
            V old = entry.value;
            entry.value = value;
            return old;
        }
    }

    addEntry(hash, key, value, index);
    return null;
}

Note the index which has been calculated注意已计算的索引

int index = (hash & 0x7FFFFFFF) % tab.length;

is passed to the addEntry() method.传递给 addEntry() 方法。 This method does a double hashing when there is a hash collision.当存在 hash 冲突时,此方法执行双重哈希。 FYR the code is as follows: FYR代码如下:

private void addEntry(int hash, K key, V value, int index) {
    modCount++;

    Entry<?,?> tab[] = table;
    if (count >= threshold) {
        // Rehash the table if the threshold is exceeded
        rehash();

        tab = table;
        hash = key.hashCode();
        index = (hash & 0x7FFFFFFF) % tab.length;
    }

    // Creates the new entry.
    @SuppressWarnings("unchecked")
    Entry<K,V> e = (Entry<K,V>) tab[index];
    tab[index] = new Entry<>(hash, key, value, e);
    count++;
}

HashMap HashMap

The storage implementation is contained in putVal() method.存储实现包含在 putVal() 方法中。 FYR code: FYR代码:

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
               boolean evict) {
    Node<K,V>[] tab; Node<K,V> p; int n, i;
    if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
    if ((p = tab[i = (n - 1) & hash]) == null)
        tab[i] = newNode(hash, key, value, null);
    else {
        Node<K,V> e; K k;
        if (p.hash == hash &&
            ((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        else if (p instanceof TreeNode)
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else {
            for (int binCount = 0; ; ++binCount) {
                if ((e = p.next) == null) {
                    p.next = newNode(hash, key, value, null);
                    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                        treeifyBin(tab, hash);
                    break;
                }
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                p = e;
            }
        }
        if (e != null) { // existing mapping for key
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            afterNodeAccess(e);
            return oldValue;
        }
    }
    ++modCount;
    if (++size > threshold)
        resize();
    afterNodeInsertion(evict);
    return null;
}

Since Java 8 on encountering hash collisions objects are stored in a Balanced Binary Tree to enhance the performance by reducing the lookup time to O(log n) over former LinkedList storage(Java 7 & previous) where it was O(n).由于 Java 8 在遇到 hash 冲突时,对象被存储在平衡二叉树中,以通过将查找时间减少到 O(log n) 来提高性能,而不是以前的 LinkedList 存储(Java 7 和以前的),它是 O(n)。 This is quite visibly different from Hashtable's approach of handling collisions.这与 Hashtable 处理冲突的方法明显不同。

HashTable & HashMap even though are mainly based on hashing principle for storage have been implemented quite differently keeping in mind several scenarios like multithreading/concurrent processing etc. HashTable 和 HashMap 尽管主要基于散列存储原理,但在实现时却完全不同,请记住多线程/并发处理等多种场景。

Also, hashcode() method belongs to Object class & returns the object ID which you can check by putting a breakpoint in your IDE & check the value in debug mode. Also, hashcode() method belongs to Object class & returns the object ID which you can check by putting a breakpoint in your IDE & check the value in debug mode.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM