Hashtable和 HashMap 的区别

318 阅读2分钟

1: 父类不一样

  • Hashtable

class Hashtable<K,V> extends Dictionary<K,V>

  • HashMap

HashMap<K, V> extends AbstractMap<K, V>

2: Capacity 不一样

  • Hashtable

this(11, 0.75f);

  • HashMap

HashMap(16, 0.75f);

3:线程安全不一样

  • HashMap : 无锁
  • Hashtable : 好多锁

4:null值

  • HashMap : null可以作为键(放在 hash 桶的第 0 个位置)
  • HashTable: key和value都不允许出现null值,否则会抛出NullPointerException异常

5:遍历方式:

  • HashMap : Iterator
  • HashTable: Enumeration** (/i,nju:mə'reiʃən/ : 计数;列举)**

6: 哈希值的使用不同

  • HashMap : 有自己的 hash 函数,重新计算自己的 Hash 值
  • HashTable: 直接使用对象的hashCode
  • ps:以下就是 hashMap 计算hash 的方式
  /**
     * 这个扰动函数,
     * Computes key.hashCode() and spreads (XORs) higher bits of hash
     * to lower.  Because the table uses power-of-two masking, sets of
     * hashes that vary only in bits above the current mask will
     * always collide. (Among known examples are sets of Float keys
     * holding consecutive whole numbers in small tables.)  So we
     * apply a transform that spreads the impact of higher bits
     * downward. There is a tradeoff between speed, utility, and
     * quality of bit-spreading. Because many common sets of hashes
     * are already reasonably distributed (so don't benefit from
     * spreading), and because we use trees to handle large sets of
     * collisions in bins, we just XOR some shifted bits in the
     * cheapest possible way to reduce systematic lossage, as well as
     * to incorporate impact of the highest bits that would otherwise
     * never be used in index calculations because of table bounds.
     *
     * 作用: 在 table 的 size 还是很大的情况下,让 key 的高 16 位,也参与路由寻址;
     */
    static final int hash(Object key) {
        int h;
        // key 是空的,直接放在 0 的位置;
        /*
         * h = 0b 0010 0101 1010 1100 0011 1111 0010 1110
         * 0b 0010 0101 1010 1100 0011 1111 0010 1110 >>>16 = 0b 0000 0000 0000 0000 0010 0101 1010 1100
         *
         *
         * 0b 0010 0101 1010 1100 0011 1111 0010 1110
         * ^
         * 0b 0000 0000 0000 0000 0010 0101 1010 1100
         *
         * 异或的结果 :
         * 0b 0010 0101 1010 1100 0001 1010 1000 0010
         */
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

7:扩容的方式不一样

  • HashTable :old*2+1
  • HashMap :2的指数 增加

参考:【Java】HashMap 和 HashTable 的区别到底是什么?