Hashtable源码解析(JDK1.8)

Posted 武培轩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hashtable源码解析(JDK1.8)相关的知识,希望对你有一定的参考价值。

   1 package java.util;
   2 
   3 import java.io.*;
   4 import java.util.concurrent.ThreadLocalRandom;
   5 import java.util.function.BiConsumer;
   6 import java.util.function.Function;
   7 import java.util.function.BiFunction;
   8 
   9 import sun.misc.SharedSecrets;
  10 
  11 /**
  12  * Hashtable存储的内容是键值对(key-value)映射,其底层实现是一个Entry数组+链表;
  13  * Hashtable和HashMap一样也是散列表,存储元素也是键值对;
  14  * HashMap允许key和value都为null,而Hashtable都不能为null,Hashtable中的映射不是有序的;
  15  * Hashtable和HashMap扩容的方法不一样,Hashtable中数组默认大小11,扩容方式是 old*2+1。
  16  * HashMap中数组的默认大小是16,而且一定是2的指数,增加为原来的2倍。
  17  * Hashtable继承于Dictionary类(Dictionary类声明了操作键值对的接口方法),实现Map接口(定义键值对接口);
  18  * Hashtable大部分类用synchronized修饰,证明Hashtable是线程安全的。
  19  */
  20 public class Hashtable<K, V>
  21         extends Dictionary<K, V>
  22         implements Map<K, V>, Cloneable, java.io.Serializable {
  23 
  24     /**
  25      * 键值对/Entry数组,每个Entry本质上是一个单向链表的表头
  26      */
  27     private transient Entry<?, ?>[] table;
  28 
  29     /**
  30      * 当前表中的Entry数量,如果超过了阈值,就会扩容,即调用rehash方法
  31      */
  32     private transient int count;
  33 
  34     /**
  35      * rehash阈值
  36      *
  37      * @serial
  38      */
  39     private int threshold;
  40 
  41     /**
  42      * 负载因子
  43      *
  44      * @serial
  45      */
  46     private float loadFactor;
  47 
  48     /**
  49      * 用来实现"fail-fast"机制的(也就是快速失败)。所谓快速失败就是在并发集合中,其进行
  50      * 迭代操作时,若有其他线程对其进行结构性的修改,这时迭代器会立马感知到,并且立即抛出
  51      * ConcurrentModificationException异常,而不是等到迭代完成之后才告诉你(你已经出错了)。
  52      */
  53     private transient int modCount = 0;
  54 
  55     /**
  56      * 版本序列号
  57      */
  58     private static final long serialVersionUID = 1421746759512286392L;
  59 
  60     /**
  61      * 指定容量大小和加载因子的构造函数
  62      *
  63      * @param initialCapacity 容量大小
  64      * @param loadFactor      负载因子
  65      * @throws IllegalArgumentException if the initial capacity is less
  66      *                                  than zero, or if the load factor is nonpositive.
  67      */
  68     public Hashtable(int initialCapacity, float loadFactor) {
  69         if (initialCapacity < 0)
  70             throw new IllegalArgumentException("Illegal Capacity: " +
  71                     initialCapacity);
  72         if (loadFactor <= 0 || Float.isNaN(loadFactor))
  73             throw new IllegalArgumentException("Illegal Load: " + loadFactor);
  74 
  75         if (initialCapacity == 0)
  76             initialCapacity = 1;
  77         this.loadFactor = loadFactor;
  78         table = new Entry<?, ?>[initialCapacity];
  79         threshold = (int) Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
  80     }
  81 
  82     /**
  83      * 指定容量大小的构造函数
  84      *
  85      * @param initialCapacity 容量大小
  86      * @throws IllegalArgumentException if the initial capacity is less
  87      *                                  than zero.
  88      */
  89     public Hashtable(int initialCapacity) {
  90         this(initialCapacity, 0.75f);
  91     }
  92 
  93     /**
  94      * 默认构造函数
  95      */
  96     public Hashtable() {
  97         // 默认构造函数,指定的容量大小是11;加载因子是0.75
  98         this(11, 0.75f);
  99     }
 100 
 101     /**
 102      * 包含子Map的构造函数
 103      *
 104      * @param t the map whose mappings are to be placed in this map.
 105      * @throws NullPointerException if the specified map is null.
 106      * @since 1.2
 107      */
 108     public Hashtable(Map<? extends K, ? extends V> t) {
 109         this(Math.max(2 * t.size(), 11), 0.75f);
 110         putAll(t);
 111     }
 112 
 113     /**
 114      * 返回容量大小
 115      *
 116      * @return the number of keys in this hashtable.
 117      */
 118     public synchronized int size() {
 119         return count;
 120     }
 121 
 122     /**
 123      * 判空
 124      *
 125      * @return <code>true</code> if this hashtable maps no keys to values;
 126      * <code>false</code> otherwise.
 127      */
 128     public synchronized boolean isEmpty() {
 129         return count == 0;
 130     }
 131 
 132     /**
 133      * 返回所有key的枚举对象
 134      *
 135      * @return an enumeration of the keys in this hashtable.
 136      * @see Enumeration
 137      * @see #elements()
 138      * @see #keySet()
 139      * @see Map
 140      */
 141     public synchronized Enumeration<K> keys() {
 142         return this.<K>getEnumeration(KEYS);
 143     }
 144 
 145     /**
 146      * 返回所有value的枚举对象
 147      *
 148      * @return an enumeration of the values in this hashtable.
 149      * @see java.util.Enumeration
 150      * @see #keys()
 151      * @see #values()
 152      * @see Map
 153      */
 154     public synchronized Enumeration<V> elements() {
 155         return this.<V>getEnumeration(VALUES);
 156     }
 157 
 158     /**
 159      * 判断是否含有该value的键值对,在Hashtable中hashCode相同的Entry用链表组织,hashCode不同的存储在Entry数组table中;
 160      *
 161      * @param value a value to search for
 162      * @return <code>true</code> if and only if some key maps to the
 163      * <code>value</code> argument in this hashtable as
 164      * determined by the <tt>equals</tt> method;
 165      * <code>false</code> otherwise.
 166      * @throws NullPointerException if the value is <code>null</code>
 167      */
 168     public synchronized boolean contains(Object value) {
 169         if (value == null) {
 170             throw new NullPointerException();
 171         }
 172 
 173         Entry<?, ?> tab[] = table;
 174         // 查找:遍历所有Entry链表
 175         for (int i = tab.length; i-- > 0; ) {
 176             for (Entry<?, ?> e = tab[i]; e != null; e = e.next) {
 177                 if (e.value.equals(value)) {
 178                     return true;
 179                 }
 180             }
 181         }
 182         return false;
 183     }
 184 
 185     /**
 186      * 判断是否包含value值对象
 187      *
 188      * @param value value whose presence in this hashtable is to be tested
 189      * @return <tt>true</tt> if this map maps one or more keys to the
 190      * specified value
 191      * @throws NullPointerException if the value is <code>null</code>
 192      * @since 1.2
 193      */
 194     public boolean containsValue(Object value) {
 195         return contains(value);
 196     }
 197 
 198     /**
 199      * 判断是否包含key键值对象
 200      *
 201      * @param key possible key
 202      * @return <code>true</code> if and only if the specified object
 203      * is a key in this hashtable, as determined by the
 204      * <tt>equals</tt> method; <code>false</code> otherwise.
 205      * @throws NullPointerException if the key is <code>null</code>
 206      * @see #contains(Object)
 207      */
 208     public synchronized boolean containsKey(Object key) {
 209         Entry<?, ?> tab[] = table;
 210         int hash = key.hashCode();
 211         /**
 212          * 计算index, % tab.length防止数组越界
 213          * index表示key对应entry所在链表表头
 214          */
 215         int index = (hash & 0x7FFFFFFF) % tab.length;
 216         for (Entry<?, ?> e = tab[index]; e != null; e = e.next) {
 217             if ((e.hash == hash) && e.key.equals(key)) {
 218                 return true;
 219             }
 220         }
 221         return false;
 222     }
 223 
 224     /**
 225      * 根据指定key查找对应value,查找原理与containsKey相同,查找成功返回value,否则返回null
 226      *
 227      * @param key the key whose associated value is to be returned
 228      * @return the value to which the specified key is mapped, or
 229      * {@code null} if this map contains no mapping for the key
 230      * @throws NullPointerException if the specified key is null
 231      * @see #put(Object, Object)
 232      */
 233     @SuppressWarnings("unchecked")
 234     public synchronized V get(Object key) {
 235         Entry<?, ?> tab[] = table;
 236         int hash = key.hashCode();
 237         int index = (hash & 0x7FFFFFFF) % tab.length;
 238         for (Entry<?, ?> e = tab[index]; e != null; e = e.next) {
 239             if ((e.hash == hash) && e.key.equals(key)) {
 240                 return (V) e.value;
 241             }
 242         }
 243         return null;
 244     }
 245 
 246     /**
 247      * 规定的最大数组容量
 248      */
 249     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
 250 
 251     /**
 252      * 当Hashtable中键值对总数超过阈值(容量*装载因子)后,内部自动调用rehash()增加容量,重新计算每个键值对的hashCode
 253      * int newCapacity = (oldCapacity << 1) + 1计算新容量 = 2 * 旧容量 + 1;并且根据新容量更新阈值
 254      */
 255     @SuppressWarnings("unchecked")
 256     protected void rehash() {
 257         int oldCapacity = table.length;
 258         Entry<?, ?>[] oldMap = table;
 259 
 260         /**
 261          * 新的大小为  原大小 * 2 + 1
 262          * 虽然不保证capacity是一个质数,但至少保证它是一个奇数
 263          */
 264         int newCapacity = (oldCapacity << 1) + 1;
 265         if (newCapacity - MAX_ARRAY_SIZE > 0) {
 266             if (oldCapacity == MAX_ARRAY_SIZE)
 267                 // Keep running with MAX_ARRAY_SIZE buckets
 268                 return;
 269             newCapacity = MAX_ARRAY_SIZE;
 270         }
 271         Entry<?, ?>[] newMap = new Entry<?, ?>[newCapacity];
 272 
 273         modCount++;
 274         threshold = (int) Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
 275         table = newMap;
 276         // 拷贝每个Entry链表
 277         for (int i = oldCapacity; i-- > 0; ) {
 278             for (Entry<K, V> old = (Entry<K, V>) oldMap[i]; old != null; ) {
 279                 Entry<K, V> e = old;
 280                 old = old.next;
 281                 // 重新计算每个Entry链表的表头索引(rehash)
 282                 int index = (e.hash & 0x7FFFFFFF) % newCapacity;
 283                 // 开辟链表节点
 284                 e.next = (Entry<K, V>) newMap[index];
 285                 // 拷贝
 286                 newMap[index] = e;
 287             }
 288         }
 289     }
 290 
 291     /**
 292      * 当键值对个数超过阈值,先进行rehash然后添加entry,否则直接添加entry
 293      */
 294     private void addEntry(int hash, K key, V value, int index) {
 295         modCount++;
 296 
 297         Entry<?, ?> tab[] = table;
 298         // 当前元素大于等于阈值,就扩容并且再计算hash值
 299         if (count >= threshold) {
 300             rehash();
 301 
 302             tab = table;
 303             hash = key.hashCode();
 304             index = (hash & 0x7FFFFFFF) % tab.length;
 305         }
 306 
 307         // Creates the new entry.
 308         @SuppressWarnings("unchecked")
 309         Entry<K, V> e = (Entry<K, V>) tab[index];
 310         // 和HashMap不同,Hashtable选择把新插入的元素放到链表最前边,而且没有使用红黑树
 311         tab[index] = new Entry<>(hash, key, value, e);
 312         count++;
 313     }
 314 
 315     /**
 316      * 设置键值对,key和value都不可为null,设置顺序:
 317      * 如果Hashtable含有key,设置(key, oldValue) -> (key, newValue);
 318      * 如果Hashtable不含有key, 调用addEntry(...)添加新的键值对;
 319      *
 320      * @param key   the hashtable key
 321      * @param value the value
 322      * @return the previous value of the specified key in this hashtable,
 323      * or <code>null</code> if it did not have one
 324      * @throws NullPointerException if the key or value is
 325      *                              <code>null</code>
 326      * @see Object#equals(Object)
 327      * @see #get(Object)
 328      */
 329     public synchronized V put(K key, V value) {
 330         // value为空抛出空指针异常
 331         if (value == null) {
 332             throw new NullPointerException();
 333         }
 334 
 335         // Makes sure the key is not already in the hashtable.
 336         Entry<?, ?> tab[] = table;
 337         /**
 338          * key的hashCode是调用Object的hashCode()方法,
 339          * 是native的方法,如果为null,就会抛出空指针异常
 340          */
 341         int hash = key.hashCode();
 342         /**
 343          * 因为hash可能为负数,所以就先和0x7FFFFFFF相与
 344          * 在HashMap中,是用 (table.length - 1) & hash 计算要放置的位置
 345          */
 346         int index = (hash & 0x7FFFFFFF) % tab.length;
 347         @SuppressWarnings("unchecked")
 348         Entry<K, V> entry = (Entry<K, V>) tab[index];
 349         for (; entry != null; entry = entry.next) {
 350             if ((entry.hash == hash) && entry.key.equals(key)) {
 351                 V old = entry.value;
 352                 entry.value = value;
 353                 return old;
 354             }
 355         }
 356         // 如果key对应的值不存在,就调用addEntry方法加入
 357         addEntry(hash, key, value, index);
 358         return null;
 359     }
 360 
 361     /**
 362      * remove操作,计算key所在链表表头table[index],然后进行单向链表的节点删除操作
 363      *
 364      * @param key the key that needs to be removed
 365      * @return the value to which the key had been mapped in this hashtable,
 366      * or <code>null</code> if the key did not have a mapping
 367      * @throws NullPointerException if the key is <code>null</code>
 368      */
 369     public synchronized V remove(Object key) {
 370         Entry<?, ?> tab[] = table;
 371         int hash = key.hashCode();
 372         int index = (hash & 0x7FFFFFFF) % tab.length;
 373         @SuppressWarnings("unchecked")
 374         Entry<K, V> e = (Entry<K, V>) tab[index];
 375         for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
 376             if ((e.hash == hash) && e.key.equals(key)) {
 377                 modCount++;
 378                 if (prev != null) {
 379                     prev.next = e.next;
 380                 } else {
 381                     tab[index] = e.next;
 382                 }
 383                 count--;
 384                 V oldValue = e.value;
 385                 e.value = null;
 386                 return oldValue;
 387             }
 388         }
 389         return null;
 390     }
 391 
 392     /**
 393      * 把所有的 映射从指定的map复制到hashTable中
 394      * 如果给定的map中的key值已经存在于hashTable中,则将会覆盖hashTable中key所对应的value(hashTable中key值不允许重复)
 395      *
 396      * @param t mappings to be stored in this map
 397      * @throws NullPointerException if the specified map is null
 398      * @since 1.2
 399      */
 400     public synchronized void putAll(Map<? extends K, ? extends V> t) {
 401         //foreach 循环map数据put到hashTable中
 402         for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
 403             put(e.getKey(), e.getValue());
 404     }
 405 
 406     /**
 407      * 清空Hashtable
 408      * 将Hashtable的table数组的值全部设为null
 409      */
 410     public synchronized void clear() {
 411         Entry<?, ?> tab[] = table;
 412         modCount++;
 413         for (int index = tab.length; --index >= 0; )
 414             tab[index] = null;
 415         count = 0;
 416     }
 417 
 418     /**
 419      * 对Hashtable的浅拷贝操作,浅拷贝所有bucket(单向链表组织形式)的表头
 420      *
 421      * @return a clone of the hashtable
 422      */
 423     public synchronized Object clone() {
 424         try {
 425             Hashtable<?, ?> t = (Hashtable<?, ?>) super.clone();
 426             t.table = new Entry<?, ?>[table.length];
 427             for (int i = table.length; i-- > 0; ) {
 428                 t.table[i] = (table[i] != null)
 429                         ? (Entry<?, ?>) table[i].clone() : null;
 430             }
 431             t.keySet = null;
 432             t.entrySet = null;
 433             t.values = null;
 434             t.modCount = 0;
 435             return t;
 436         } catch (CloneNotSupportedException e) {
 437             // this shouldn‘t happen, since we are Cloneable
 438             throw new InternalError(e);
 439         }
 440     }
 441 
 442     /**
 443      * 返回Hashtable对象的String表达方式,一系列以括号和逗号,空格分隔的Entry,如{key1=value1, key2=value2}
 444      *
 445      * @return a string representation of this hashtable
 446      */
 447     public synchronized String toString() {
 448         int max = size() - 1;
 449         if (max == -1)
 450             return "{}";
 451 
 452         StringBuilder sb = new StringBuilder();
 453         Iterator<Map.Entry<K, V>> it = entrySet().iterator();
 454 
 455         sb.append(‘{‘);
 456         for (int i = 0; ; i++) {
 457             Map.Entry<K, V> e = it.next();
 458             K key = e.getKey();
 459             V value = e.getValue();
 460             sb.append(key == this ? "(this Map)" : key.toString());
 461             sb.append(‘=‘);
 462             sb.append(value == this ? "(this Map)" : value.toString());
 463 
 464             if (i == max)
 465                 return sb.append(‘}‘).toString();
 466             sb.append(", ");
 467         }
 468     }
 469 
 470 
 471     private <T> Enumeration<T> getEnumeration(int type) {
 472         if (count == 0) {
 473             return Collections.emptyEnumeration();
 474         } else {
 475             return new Enumerator<>(type, false);
 476         }
 477     }
 478 
 479     /**
 480      * 获得迭代器
 481      */
 482     private <T> Iterator<T> getIterator(int type) {
 483         if (count == 0) {
 484             return Collections.emptyIterator();
 485         } else {
 486             return new Enumerator<>(type, true);
 487         }
 488     }
 489 
 490     // 视图
 491 
 492     /**
 493      * 以下每个字段初始化后会包含一个首次请求后的指定视图,视图是无状态的,所以不必创建多个
 494      */
 495     private transient volatile Set<K> keySet;
 496     private transient volatile Set<Map.Entry<K, V>> entrySet;
 497     private transient volatile Collection<V> values;
 498 
 499     /**
 500      * 返回一个被synchronizedSet封装后的KeySet对象
 501      * synchronizedSet封装的目的是对KeySet的所有方法都添加synchronized,实现多线程同步
 502      */
 503     public Set<K> keySet() {
 504         if (keySet == null)
 505             keySet = Collections.synchronizedSet(new KeySet(), this);
 506         return keySet;
 507     }
 508 
 509     /**
 510      * Hashtable的Key的Set集合
 511      * KeySet继承于AbstractSet,所以,KeySet中的元素没有重复的
 512      */
 513     private class KeySet extends AbstractSet<K> {
 514         public Iterator<K> iterator() {
 515             return getIterator(KEYS);
 516         }
 517 
 518         public int size() {
 519             return count;
 520         }
 521 
 522         public boolean contains(Object o) {
 523             return containsKey(o);
 524         }
 525 
 526         public boolean remove(Object o) {
 527             return Hashtable.this.remove(o) != null;
 528         }
 529 
 530         public void clear() {
 531             Hashtable.this.clear();
 532         }
 533     }
 534 
 535     /**
 536      * 返回一个被synchronizedSet封装后的EntrySet对象
 537      * synchronizedSet封装的目的是对EntrySet的所有方法都添加synchronized,实现多线程同步
 538      */
 539     public Set<Map.Entry<K, V>> entrySet() {
 540         if (entrySet == null)
 541             entrySet = Collections.synchronizedSet(new EntrySet(), this);
 542         return entrySet;
 543     }
 544 
 545     /**
 546      * Hashtable的Entry的Set集合
 547      * EntrySet继承于AbstractSet,所以,EntrySet中的元素没有重复的
 548      */
 549     private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
 550         public Iterator<Map.Entry<K, V>> iterator() {
 551             return getIterator(ENTRIES);
 552         }
 553 
 554         public boolean add(Map.Entry<K, V> o) {
 555             return super.add(o);
 556         }
 557 
 558         /**
 559          * 查找EntrySet中是否包含Object(0)
 560          * 首先,在table中找到o对应的Entry(Entry是一个单向链表)
 561          * 然后,查找Entry链表中是否存在Object
 562          */
 563         public boolean contains(Object o) {
 564             if (!(o instanceof Map.Entry))
 565                 return false;
 566             Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
 567             Object key = entry.getKey();
 568             Entry<?, ?>[] tab = table;
 569             int hash = key.hashCode();
 570             int index = (hash & 0x7FFFFFFF) % tab.length;
 571 
 572             for (Entry<?, ?> e = tab[index]; e != null; e = e.next)
 573                 if (e.hash == hash && e.equals(entry))
 574                     return true;
 575             return false;
 576         }
 577 
 578         /**
 579          * 删除元素Object(0)
 580          * 首先,在table中找到o对应的Entry(Entry是一个单向链表)
 581          * 然后,删除链表中的元素Object
 582          */
 583         public boolean remove(Object o) {
 584             if (!(o instanceof Map.Entry))
 585                 return false;
 586             Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
 587             Object key = entry.getKey();
 588             Entry<?, ?>[] tab = table;
 589             int hash = key.hashCode();
 590             int index = (hash & 0x7FFFFFFF) % tab.length;
 591 
 592             @SuppressWarnings("unchecked")
 593             Entry<K, V> e = (Entry<K, V>) tab[index];
 594             for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
 595                 if (e.hash == hash && e.equals(entry)) {
 596                     modCount++;
 597                     if (prev != null)
 598                         prev.next = e.next;
 599                     else
 600                         tab[index] = e.next;
 601 
 602                     count--;
 603                     e.value = null;
 604                     return true;
 605                 }
 606             }
 607             return false;
 608         }
 609 
 610         public int size() {
 611             return count;
 612         }
 613 
 614         public void clear() {
 615             Hashtable.this.clear();
 616         }
 617     }
 618 
 619     /**
 620      * 返回一个被synchronizedCollection封装后的ValueCollection对象
 621      * synchronizedCollection封装的目的是对ValueCollection的所有方法都添加synchronized,实现多线程同步
 622      */
 623     public Collection<V> values() {
 624         if (values == null)
 625             values = Collections.synchronizedCollection(new ValueCollection(),
 626                     this);
 627         return values;
 628     }
 629 
 630     /**
 631      * Hashtable的value的Collection集合。
 632      * ValueCollection继承于AbstractCollection,所以,ValueCollection中的元素可以重复的。
 633      */
 634     private class ValueCollection extends AbstractCollection<V> {
 635         public Iterator<V> iterator() {
 636             return getIterator(VALUES);
 637         }
 638 
 639         public int size() {
 640             return count;
 641         }
 642 
 643         public boolean contains(Object o) {
 644             return containsValue(o);
 645         }
 646 
 647         public void clear() {
 648             Hashtable.this.clear();
 649         }
 650     }
 651 
 652     // Comparison and hashing
 653 
 654     /**
 655      * 重新equals()函数
 656      * 若两个Hashtable的所有key-value键值对都相等,则判断它们两个相等
 657      *
 658      * @param o object to be compared for equality with this hashtable
 659      * @return true if the specified Object is equal to this Map
 660      * @see Map#equals(Object)
 661      * @since 1.2
 662      */
 663     public synchronized boolean equals(Object o) {
 664         if (o == this)
 665             return true;
 666 
 667         if (!(o instanceof Map))
 668             return false;
 669         Map<?, ?> t = (Map<?, ?>) o;
 670         if (t.size() != size())
 671             return false;
 672 
 673         try {
 674             /**
 675              * 通过迭代器依次取出当前Hashtable的key-value键值对
 676              * 并判断该键值对,存在于Hashtable(o)中。
 677              * 若不存在,则立即返回false;否则,遍历完“当前Hashtable”并返回true。
 678              */
 679             Iterator<Map.Entry<K, V>> i = entrySet().iterator();
 680             while (i.hasNext()) {
 681                 Map.Entry<K, V> e = i.next();
 682                 K key = e.getKey();
 683                 V value = e.getValue();
 684                 if (value == null) {
 685                     if (!(t.get(key) == null && t.containsKey(key)))
 686                         return false;
 687                 } else {
 688                     if (!value.equals(t.get(key)))
 689                         return false;
 690                 }
 691             }
 692         } catch (ClassCastException unused) {
 693             return false;
 694         } catch (NullPointerException unused) {
 695             return false;
 696         }
 697 
 698         return true;
 699     }
 700 
 701     /**
 702      * 计算Hashtable的哈希值
 703      *
 704      * @see Map#hashCode()
 705      * @since 1.2
 706      */
 707     public synchronized int hashCode() {
 708         int h = 0;
 709         //若 Hashtable的实际大小为0 或者 加载因子<0,则返回0
 710         if (count == 0 || loadFactor < 0)
 711             return h;  // Returns zero
 712 
 713         loadFactor = -loadFactor;  // Mark hashCode computation in progress
 714         Entry<?, ?>[] tab = table;
 715         //返回Hashtable中的每个Entry的key和value的异或值的总和
 716         for (Entry<?, ?> entry : tab) {
 717             while (entry != null) {
 718                 h += entry.hashCode();
 719                 entry = entry.next;
 720             }
 721         }
 722 
 723         loadFactor = -loadFactor;  // Mark hashCode computation complete
 724 
 725         return h;
 726     }
 727 
 728     @Override
 729     public synchronized V getOrDefault(Object key, V defaultValue) {
 730         V result = get(key);
 731         return (null == result) ? defaultValue : result;
 732     }
 733 
 734     @SuppressWarnings("unchecked")
 735     @Override
 736     public synchronized void forEach(BiConsumer<? super K, ? super V> action) {
 737         Objects.requireNonNull(action);     // explicit check required in case
 738         // table is empty.
 739         final int expectedModCount = modCount;
 740 
 741         Entry<?, ?>[] tab = table;
 742         for (Entry<?, ?> entry : tab) {
 743             while (entry != null) {
 744                 action.accept((K) entry.key, (V) entry.value);
 745                 entry = entry.next;
 746 
 747                 if (expectedModCount != modCount) {
 748                     throw new ConcurrentModificationException();
 749                 }
 750             }
 751         }
 752     }
 753 
 754     @SuppressWarnings("unchecked")
 755     @Override
 756     public synchronized void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
 757         Objects.requireNonNull(function);     // explicit check required in case
 758         // table is empty.
 759         final int expectedModCount = modCount;
 760 
 761         Entry<K, V>[] tab = (Entry<K, V>[]) table;
 762         for (Entry<K, V> entry : tab) {
 763             while (entry != null) {
 764                 entry.value = Objects.requireNonNull(
 765                         function.apply(entry.key, entry.value));
 766                 entry = entry.next;
 767 
 768                 if (expectedModCount != modCount) {
 769                     throw new ConcurrentModificationException();
 770                 }
 771             }
 772         }
 773     }
 774 
 775     @Override
 776     public synchronized V putIfAbsent(K key, V value) {
 777         Objects.requireNonNull(value);
 778 
 779         // Makes sure the key is not already in the hashtable.
 780         Entry<?, ?> tab[] = table;
 781         int hash = key.hashCode();
 782         int index = (hash & 0x7FFFFFFF) % tab.length;
 783         @SuppressWarnings("unchecked")
 784         Entry<K, V> entry = (Entry<K, V>) tab[index];
 785         for (; entry != null; entry = entry.next) {
 786             if ((entry.hash == hash) && entry.key.equals(key)) {
 787                 V old = entry.value;
 788                 if (old == null) {
 789                     entry.value = value;
 790                 }
 791                 return old;
 792             }
 793         }
 794 
 795         addEntry(hash, key, value, index);
 796         return null;
 797     }
 798 
 799     @Override
 800     public synchronized boolean remove(Object key, Object value) {
 801         Objects.requireNonNull(value);
 802 
 803         Entry<?, ?> tab[] = table;
 804         int hash = key.hashCode();
 805         int index = (hash & 0x7FFFFFFF) % tab.length;
 806         @SuppressWarnings("unchecked")
 807         Entry<K, V> e = (Entry<K, V>) tab[index];
 808         for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
 809             if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) {
 810                 modCount++;
 811                 if (prev != null) {
 812                     prev.next = e.next;
 813                 } else {
 814                     tab[index] = e.next;
 815                 }
 816                 count--;
 817                 e.value = null;
 818                 return true;
 819             }
 820         }
 821         return false;
 822     }
 823 
 824     @Override
 825     public synchronized boolean replace(K key, V oldValue, V newValue) {
 826         Objects.requireNonNull(oldValue);
 827         Objects.requireNonNull(newValue);
 828         Entry<?, ?> tab[] = table;
 829         int hash = key.hashCode();
 830         int index = (hash & 0x7FFFFFFF) % tab.length;
 831         @SuppressWarnings("unchecked")
 832         Entry<K, V> e = (Entry<K, V>) tab[index];
 833         for (; e != null; e = e.next) {
 834             if ((e.hash == hash) && e.key.equals(key)) {
 835                 if (e.value.equals(oldValue)) {
 836                     e.value = newValue;
 837                     return true;
 838                 } else {
 839                     return false;
 840                 }
 841             }
 842         }
 843         return false;
 844     }
 845 
 846     /**
 847      * 替换
 848      *
 849      * @param key
 850      * @param value
 851      * @return
 852      */
 853     @Override
 854     public synchronized V replace(K key, V value) {
 855         Objects.requireNonNull(value);
 856         Entry<?, ?> tab[] = table;
 857         int hash = key.hashCode();
 858         int index = (hash & 0x7FFFFFFF) % tab.length;
 859         @SuppressWarnings("unchecked")
 860         Entry<K, V> e = (Entry<K, V>) tab[index];
 861         for (; e != null; e = e.next) {
 862             if ((e.hash == hash) && e.key.equals(key)) {
 863                 V oldValue = e.value;
 864                 e.value = value;
 865                 return oldValue;
 866             }
 867         }
 868         return null;
 869     }
 870 
 871     @Override
 872     public synchronized V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
 873         Objects.requireNonNull(mappingFunction);
 874 
 875         Entry<?, ?> tab[] = table;
 876         int hash = key.hashCode();
 877         int index = (hash & 0x7FFFFFFF) % tab.length;
 878         @SuppressWarnings("unchecked")
 879         Entry<K, V> e = (Entry<K, V>) tab[index];
 880         for (; e != null; e = e.next) {
 881             if (e.hash == hash && e.key.equals(key)) {
 882                 // Hashtable not accept null value
 883                 return e.value;
 884             }
 885         }
 886 
 887         V newValue = mappingFunction.apply(key);
 888         if (newValue != null) {
 889             addEntry(hash, key, newValue, index);
 890         }
 891 
 892         return newValue;
 893     }
 894 
 895     @Override
 896     public synchronized V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
 897         Objects.requireNonNull(remappingFunction);
 898 
 899         Entry<?, ?> tab[] = table;
 900         int hash = key.hashCode();
 901         int index = (hash & 0x7FFFFFFF) % tab.length;
 902         @SuppressWarnings("unchecked")
 903         Entry<K, V> e = (Entry<K, V>) tab[index];
 904         for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
 905             if (e.hash == hash && e.key.equals(key)) {
 906                 V newValue = remappingFunction.apply(key, e.value);
 907                 if (newValue == null) {
 908                     modCount++;
 909                     if (prev != null) {
 910                         prev.next = e.next;
 911                     } else {
 912                         tab[index] = e.next;
 913                     }
 914                     count--;
 915                 } else {
 916                     e.value = newValue;
 917                 }
 918                 return newValue;
 919             }
 920         }
 921         return null;
 922     }
 923 
 924     @Override
 925     public synchronized V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
 926         Objects.requireNonNull(remappingFunction);
 927 
 928         Entry<?, ?> tab[] = table;
 929         int hash = key.hashCode();
 930         int index = (hash & 0x7FFFFFFF) % tab.length;
 931         @SuppressWarnings("unchecked")
 932         Entry<K, V> e = (Entry<K, V>) tab[index];
 933         for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
 934             if (e.hash == hash && Objects.equals(e.key, key)) {
 935                 V newValue = remappingFunction.apply(key, e.value);
 936                 if (newValue == null) {
 937                     modCount++;
 938                     if (prev != null) {
 939                         prev.next = e.next;
 940                     } else {
 941                         tab[index] = e.next;
 942                     }
 943                     count--;
 944                 } else {
 945                     e.value = newValue;
 946                 }
 947                 return newValue;
 948             }
 949         }
 950 
 951         V newValue = remappingFunction.apply(key, null);
 952         if (newValue != null) {
 953             addEntry(hash, key, newValue, index);
 954         }
 955 
 956         return newValue;
 957     }
 958 
 959     @Override
 960     public synchronized V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
 961         Objects.requireNonNull(remappingFunction);
 962 
 963         Entry<?, ?> tab[] = table;
 964         int hash = key.hashCode();
 965         int index = (hash & 0x7FFFFFFF) % tab.length;
 966         @SuppressWarnings("unchecked")
 967         Entry<K, V> e = (Entry<K, V>) tab[index];
 968         for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
 969             if (e.hash == hash && e.key.equals(key)) {
 970                 V newValue = remappingFunction.apply(e.value, value);
 971                 if (newValue == null) {
 972                     modCount++;
 973                     if (prev != null) {
 974                         prev.next = e.next;
 975                     } else {
 976                         tab[index] = e.next;
 977                     }
 978                     count--;
 979                 } else {
 980                     e.value = newValue;
 981                 }
 982                 return newValue;
 983             }
 984         }
 985 
 986         if (value != null) {
 987             addEntry(hash, key, value, index);
 988         }
 989 
 990         return value;
 991     }
 992 
 993     /**
 994      * 将Hashtable的总的容量,实际容量,所有的Entry都写入到输出流中
 995      */
 996     private void writeObject(java.io.ObjectOutputStream s)
 997             throws IOException {
 998         Entry<Object, Object> entryStack = null;
 999 
1000         synchronized (this) {
1001             // Write out the threshold and loadFactor
1002             s.defaultWriteObject();
1003 
1004             // Write out the length and count of elements
1005             s.writeInt(table.length);
1006             s.writeInt(count);
1007 
1008             // Stack copies of the entries in the table
1009             for (int index = 0; index < table.length; index++) {
1010                 Entry<?, ?> entry = table[index];
1011 
1012                 while (entry != null) {
1013                     entryStack =
1014                             new Entry<>(0, entry.key, entry.value, entryStack);
1015                     entry = entry.next;
1016                 }
1017             }
1018         }
1019 
1020         // Write out the key/value objects from the stacked entries
1021         while (entryStack != null) {
1022             s.writeObject(entryStack.key);
1023             s.writeObject(entryStack.value);
1024             entryStack = entryStack.next;
1025         }
1026     }
1027 
1028     /**
1029      * 将Hashtable的总的容量,实际容量,所有的Entry依次读出
1030      */
1031     private void readObject(java.io.ObjectInputStream s)
1032             throws IOException, ClassNotFoundException {
1033         // Read in the threshold and loadFactor
1034         s.defaultReadObject();
1035 
1036         // Validate loadFactor (ignore threshold - it will be re-computed)
1037         if (loadFactor <= 0 || Float.isNaN(loadFactor))
1038             throw new StreamCorruptedException("Illegal Load: " + loadFactor);
1039 
1040         // Read the original length of the array and number of elements
1041         int origlength = s.readInt();
1042         int elements = s.readInt();
1043 
1044         // Validate # of elements
1045         if (elements < 0)
1046             throw new StreamCorruptedException("Illegal # of Elements: " + elements);
1047 
1048         // Clamp original length to be more than elements / loadFactor
1049         // (this is the invariant enforced with auto-growth)
1050         origlength = Math.max(origlength, (int) (elements / loadFactor) + 1);
1051 
1052         // Compute new length with a bit of room 5% + 3 to grow but
1053         // no larger than the clamped original length.  Make the length
1054         // odd if it‘s large enough, this helps distribute the entries.
1055         // Guard against the length ending up zero, that‘s not valid.
1056         int length = (int) ((elements + elements / 20) / loadFactor) + 3;
1057         if (length > elements && (length & 1) == 0)
1058             length--;
1059         length = Math.min(length, origlength);
1060 
1061         // Check Map.Entry[].class since it‘s the nearest public type to
1062         // what we‘re actually creating.
1063         SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, length);
1064         table = new Entry<?, ?>[length];
1065         threshold = (int) Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
1066         count = 0;
1067 
1068         // Read the number of elements and then all the key/value objects
1069         for (; elements > 0; elements--) {
1070             @SuppressWarnings("unchecked")
1071             K key = (K) s.readObject();
1072             @SuppressWarnings("unchecked")
1073             V value = (V) s.readObject();
1074             // sync is eliminated for performance
1075             reconstitutionPut(table, key, value);
1076         }
1077     }
1078 
1079     /**
1080      * readObject使用的put方法(重建put),因为put方法支持重写,并且子类尚未初始化的时候不能调用put方法,所以就提供了reconstitutionPut
1081      * 它和常规put方法有几点不同,不检测rehash,因为初始元素数目已知。modCount不会自增,因为我们是在创建一个新的实例。
1082      */
1083     private void reconstitutionPut(Entry<?, ?>[] tab, K key, V value)
1084             throws StreamCorruptedException {
1085         if (value == null) {
1086             throw new java.io.StreamCorruptedException();
1087         }
1088         // 确保Key不在Hashtable中
1089         // 反序列化过程中不应该 会发生的情况
1090         int hash = key.hashCode();
1091         int index = (hash & 0x7FFFFFFF) % tab.length;
1092         for (Entry<?, ?> e = tab[index]; e != null; e = e.next) {
1093             //反序列化过程中如果出现Key值重复,抛出异常StreamCorruptedException
1094             if ((e.hash == hash) && e.key.equals(key)) {
1095                 throw new java.io.StreamCorruptedException();
1096             }
1097         }
1098         // 创建新的Entry.
1099         @SuppressWarnings("unchecked")
1100         Entry<K, V> e = (Entry<K, V>) tab[index];
1101         tab[index] = new Entry<>(hash, key, value, e);
1102         count++;
1103     }
1104 
1105     /**
1106      * Hashtable的Entry节点,它本质上是一个单向链表。
1107      * 因此,我们能推断出Hashtable是由拉链法实现的散列表
1108      */
1109     private static class Entry<K, V> implements Map.Entry<K, V> {
1110         final int hash;
1111         final K key;
1112         V value;
1113         Entry<K, V> next;
1114 
1115         protected Entry(int hash, K key, V value, Entry<K, V> next) {
1116             this.hash = hash;
1117             this.key = key;
1118             this.value = value;
1119             this.next = next;
1120         }
1121 
1122         @SuppressWarnings("unchecked")
1123         protected Object clone() {
1124             return new Entry<>(hash, key, value,
1125                     (next == null ? null : (Entry<K, V>) next.clone()));
1126         }
1127 
1128         // Map.Entry Ops
1129 
1130         public K getKey() {
1131             return key;
1132         }
1133 
1134         public V getValue() {
1135             return value;
1136         }
1137 
1138         // 进行判断value是否为空,即不允许value为空,其实key也不能为空
1139         public V setValue(V value) {
1140             if (value == null)
1141                 throw new NullPointerException();
1142 
1143             V oldValue = this.value;
1144             this.value = value;
1145             return oldValue;
1146         }
1147 
1148         // 覆盖equals()方法,判断两个Entry是否相等。
1149         // 若两个Entry的key和value都相等,则认为它们相等。
1150         public boolean equals(Object o) {
1151             if (!(o instanceof Map.Entry))
1152                 return false;
1153             Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1154 
1155             return (key == null ? e.getKey() == null : key.equals(e.getKey())) &&
1156                     (value == null ? e.getValue() == null : value.equals(e.getValue()));
1157         }
1158 
1159         public int hashCode() {
1160             // 直接用hash进行异或,与HashMap不同
1161             return hash ^ Objects.hashCode(value);
1162         }
1163 
1164         public String toString() {
1165             return key.toString() + "=" + value.toString();
1166         }
1167     }
1168 
1169     // Types of Enumerations/Iterations
1170     private static final int KEYS = 0;
1171     private static final int VALUES = 1;
1172     private static final int ENTRIES = 2;
1173 
1174     /**
1175      * Enumerator的作用是提供了通过elements()遍历Hashtable的接口和通过entrySet()遍历Hashtable的接口。
1176      * 因为,它同时实现了 Enumerator接口和Iterator接口。
1177      */
1178     private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
1179         // 指向Hashtable的table
1180         Entry<?, ?>[] table = Hashtable.this.table;
1181         // Hashtable的总的大小
1182         int index = table.length;
1183         Entry<?, ?> entry;
1184         Entry<?, ?> lastReturned;
1185         int type;
1186 
1187         /**
1188          * Enumerator是 迭代器(Iterator) 还是 枚举类(Enumeration)的标志
1189          * iterator为true,表示它是迭代器;否则,是枚举类。
1190          */
1191         boolean iterator;
1192 
1193         /**
1194          * 在将Enumerator当作迭代器使用时会用到,用来实现fail-fast机制。
1195          */
1196         protected int expectedModCount = modCount;
1197 
1198         Enumerator(int type, boolean iterator) {
1199             this.type = type;
1200             this.iterator = iterator;
1201         }
1202 
1203         /**
1204          * 从遍历table的数组的末尾向前查找,直到找到不为null的Entry。
1205          */
1206         public boolean hasMoreElements() {
1207             Entry<?, ?> e = entry;
1208             int i = index;
1209             Entry<?, ?>[] t = table;
1210             /* Use locals for faster loop iteration */
1211             while (e == null && i > 0) {
1212                 e = t[--i];
1213             }
1214             entry = e;
1215             index = i;
1216             return e != null;
1217         }
1218 
1219         /**
1220          * 获取下一个元素
1221          * 注意:从hasMoreElements() 和nextElement() 可以看出Hashtable的elements()遍历方式
1222          * 首先,从后向前的遍历table数组。table数组的每个节点都是一个单向链表(Entry)。
1223          * 然后,依次向后遍历单向链表Entry。
1224          */
1225         @SuppressWarnings("unchecked")
1226         public T nextElement() {
1227             Entry<?, ?> et = entry;
1228             int i = index;
1229             Entry<?, ?>[] t = table;
1230             /* Use locals for faster loop iteration */
1231             while (et == null && i > 0) {
1232                 et = t[--i];
1233             }
1234             entry = et;
1235             index = i;
1236             if (et != null) {
1237                 Entry<?, ?> e = lastReturned = entry;
1238                 entry = e.next;
1239                 return type == KEYS ? (T) e.key : (type == VALUES ? (T) e.value : (T) e);
1240             }
1241             throw new NoSuchElementException("Hashtable Enumerator");
1242         }
1243 
1244         // 迭代器Iterator的判断是否存在下一个元素
1245         // 实际上,它是调用的hasMoreElements()
1246         public boolean hasNext() {
1247             return hasMoreElements();
1248         }
1249 
1250         // 迭代器获取下一个元素
1251         // 实际上,它是调用的nextElement()
1252         public T next() {
1253             if (modCount != expectedModCount)
1254                 throw new ConcurrentModificationException();
1255             return nextElement();
1256         }
1257 
1258         // 迭代器的remove()接口。
1259         // 首先,它在table数组中找出要删除元素所在的Entry,
1260         // 然后,删除单向链表Entry中的元素。
1261         public void remove() {
1262             if (!iterator)
1263                 throw new UnsupportedOperationException();
1264             if (lastReturned == null)
1265                 throw new IllegalStateException("Hashtable Enumerator");
1266             if (modCount != expectedModCount)
1267                 throw new ConcurrentModificationException();
1268 
1269             synchronized (Hashtable.this) {
1270                 Entry<?, ?>[] tab = Hashtable.this.table;
1271                 int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;
1272 
1273                 //获取该槽位第一个元素
1274                 @SuppressWarnings("unchecked")
1275                 Entry<K, V> e = (Entry<K, V>) tab[index];
1276                 //从单链表的一端向后遍历
1277                 for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
1278                     //当前元素即为上一个返回元素
1279                     if (e == lastReturned) {
1280                         modCount++;
1281                         expectedModCount++;
1282                         //删除上一个元素
1283                         if (prev == null)
1284                             tab[index] = e.next;
1285                         else
1286                             prev.next = e.next;
1287                         count--;
1288                         lastReturned = null;
1289                         return;
1290                     }
1291                 }
1292                 throw new ConcurrentModificationException();
1293             }
1294         }
1295     }
1296 }

 

以上是关于Hashtable源码解析(JDK1.8)的主要内容,如果未能解决你的问题,请参考以下文章

java集合系列(10)Hashtable源码分析(jdk1.8,推荐)

源码分析--ConcurrentHashMap与HashTable(JDK1.8)

HashTable源码分析

源码分析:JDK1.8 ConcurrentHashMap

源码解析JDK1.8-HashMap链表成环的问题解决方案

HashMap底层源码与实现逻辑