Java集合类HashTable与HashMap的区别——源码分析

点击查看Java集合类合集

1.继承的父类不同

public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>, Cloneable, Serializable

HashTable继承的是Dictionary类,而HashMap继承的是AbstractMap类

2.扩容机制不同

HashTable初始的容量是11,HashMap是16.他俩的负载因子都是0.75。当需要扩容时,HashTable的容量变为当前值2+1;而HashMap只是当前值2;

HashTable

protected void rehash() {
    
    
        int var1 = this.table.length;
        Hashtable.Entry[] var2 = this.table;
        //翻倍+1
        int var3 = (var1 << 1) + 1;
        if (var3 - 2147483639 > 0) {
    
    
            if (var1 == 2147483639) {
    
    
                return;
            }

            var3 = 2147483639;
        }

HashMap

void addEntry(int var1, K var2, V var3, int var4) {
    
    
        if (this.size >= this.threshold && null != this.table[var4]) {
    
    
        //翻倍
            this.resize(2 * this.table.length);
            var1 = null != var2 ? this.hash(var2) : 0;
            var4 = indexFor(var1, this.table.length);
        }

        this.createEntry(var1, var2, var3, var4);
    }

3.哈希值和下标计算方式不同

HashTable的哈希值就是利用key值的hashCode()方法获得。然后用哈希值与0X7FFFFFF即二进制为31个1即2147483647进行&操作。(将符号位变成0)。然后用得到的值与数组长度进行取模运算,得到下标。
HashMap是利用自己的哈希算法。先利用hashCode方法获得到哈希值,然后将高位尽量移到地位(JDK1.7),或者将高16位移到低位(JDK1.8),然后进行亦或运算得到最终的哈希值。

HashTable

//计算哈希值
private int hash(Object var1) {
    
    
		//直接调用hashCode方法
        return this.hashSeed ^ var1.hashCode();
    }

//计算下标
int var4 = (var3 & 2147483647) % var2.length;

HashMap

final int hash(Object var1) {
    
    
        int var2 = this.hashSeed;
        if (0 != var2 && var1 instanceof String) {
    
    
            return Hashing.stringHash32((String)var1);
        } else {
    
    
            var2 ^= var1.hashCode();
      		//将高位尽量移到低位
            var2 ^= var2 >>> 20 ^ var2 >>> 12;
            return var2 ^ var2 >>> 7 ^ var2 >>> 4;
        }
    }
    //获取下标(哈希值与数组长度-1进行&运算)
    static int indexFor(int var0, int var1) {
    
    
        return var0 & var1 - 1;

4.HashTable的Key-Value都不能为null

会抛出空指针异常

5.线程安全

HashTable是线程安全的。因为HashTable给那些可能产生多线程线程并发错误的方法,加上了synchronized。但是这样效率会大大降低

6.遍历方式不同

HashTable用的是Enumeration。HashMap是迭代器

猜你喜欢

转载自blog.csdn.net/qq_30033509/article/details/109232037