前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hashtable源码解析(JDK1.8)

Hashtable源码解析(JDK1.8)

作者头像
武培轩
发布2018-04-18 16:53:44
6570
发布2018-04-18 16:53:44
举报
文章被收录于专栏:武培轩的专栏武培轩的专栏
代码语言:javascript
复制
   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 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档