HashMap集合put函数源码阅读记录
2018-03-01 00:00
288 查看
在阅读put函数源码前,首先看看会用到的几个变量
首先看Map集合中最常用的 put(K key, V value) 函数
当存储的key值为null时会调用putValueForNullKey(V value),当key值不为空的情况见注释,putValueForNullKey函数代码如下
在这里判断了,当entry为空时,会先调用addNewEntryForNullKey()函数,调用该函数创建一个HashMapEntry对象,新创建出来的HashMapEntry被entryForNullKey所引用。
当entry不为空时,说明之前已经存在一个entryForNullKey的引用,则直接将旧的value替换成新的value,并且返回旧的value值。
/** * 用于记录HashMap集合中增、删、改的次数 * 该值会在初始化迭代器时存储在一个局部变量expectedModCount中 * 由于HashMap不是线程安全的,因此在使用迭代器时,如果有其它线程修改了map,会造成modCount的值与expectedModCount不一至,将会抛出ConcurrentModificationException异常 */ transient int modCount; /** * 用于表示key为空的条目 */ transient HashMapEntry<K, V> entryForNullKey; /** * HashMap集合大小的阈值 */ private transient int threshold;
首先看Map集合中最常用的 put(K key, V value) 函数
/** * Maps the specified key to the specified value. * * @param key * the key. * @param value * the value. * @return the value of any previous mapping with the specified key or * {@code null} if there was no such mapping. */ @Override public V put(K key, V value) { if (key == null) { return putValueForNullKey(value); } // 计算key的hash值 int hash = Collections.secondaryHash(key); HashMapEntry<K, V>[] tab = table; // 根据hash值计算存储的位置 int index = hash & (tab.length - 1); // 循环偏历entry数组,判断key对应的entry是否存在,如果对应的entry已经存在,则直接将旧的entry.value修改为新的value,并且返回旧的value for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) { // 判断hash、key值是否完全都相同 if (e.hash == hash && key.equals(e.key)) { preModify(e); V oldValue = e.value; e.value = value; return oldValue; } } // No entry for (non-null) key is present; create one modCount++; // 记录修改次数 // 判断当前map集合的长度是否超出阈值 if (size++ > threshold) { // 扩容,并且重新生成Hash表 tab = doubleCapacity(); // 根据新生成的hash表重新计算存储的位置 index = hash & (tab.length - 1); } // 创建对应的entry数据并保存在对应的存储位置 addNewEntry(key, value, hash, index); return null; }
当存储的key值为null时会调用putValueForNullKey(V value),当key值不为空的情况见注释,putValueForNullKey函数代码如下
private V putValueForNullKey(V value) { HashMapEntry<K, V> entry = entryForNullKey; if (entry == null) { addNewEntryForNullKey(value); size++; modCount++; return null; } else { preModify(entry); V oldValue = entry.value; entry.value = value; return oldValue; } }
在这里判断了,当entry为空时,会先调用addNewEntryForNullKey()函数,调用该函数创建一个HashMapEntry对象,新创建出来的HashMapEntry被entryForNullKey所引用。
当entry不为空时,说明之前已经存在一个entryForNullKey的引用,则直接将旧的value替换成新的value,并且返回旧的value值。
/** * Creates a new entry for the null key, and the given value and * inserts it into the hash table. This method is called by put * (and indirectly, putAll), and overridden by LinkedHashMap. */ void addNewEntryForNullKey(V value) { entryForNullKey = new HashMapEntry<K, V>(null, value, 0, null); }
相关文章推荐
- java集合源码阅读笔记-HashMap
- HashMap源码阅读记录
- JDK 1.7源码阅读笔记(七)集合类之HashMap
- JAVA 集合类(java.util)源码阅读笔记------HashMap
- Java集合源码阅读之HashMap
- HashMap源码阅读
- 集合源码部分记录
- Java集合---HashMap源码剖析
- Java集合---HashMap源码剖析
- Java集合---HashMap源码剖析
- 集合详解(四)----HashSet和HashMap源码剖析(JDK1.7)
- 19-Map集合-09-常用对象API(集合框架-Map集合-LinkedHashMap&关联源码)
- Java集合源码阅读笔记(1)
- java集合架构____HashMap源码分析
- currenthashmap源码阅读
- Java集合系列之HashMap源码分析
- Java集合---HashMap源码剖析
- hashmap源码阅读
- java_集合体系之WeakHashMap详解、源码及示例——11
- Java 集合框架源码分析(三)——HashMap