zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    关于使用Java Mail进行邮件发送,抛出Could not connect to SMTP host: xx@xxx.com, port: 25的异常可能
    百度地图和solr展示资源和附近等功能的实现 四
    Python爬虫入门-3
    Python爬虫入门-2
    Python爬虫入门-1
    Python装饰器专题-限制函数调用次数(10s调用一次)
    32个Python爬虫项目让你一次吃到撑
    时间复杂度趣图分析
    各类数据库默认端口总结
    ansible使用三(ansible roles)
  • 原文地址:https://www.cnblogs.com/wupeixuan/p/8620197.html
Copyright © 2011-2022 走看看