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 }