java源码解析---LinkedHashMap

  1 package explain;
  2
  3 import java.util.function.Consumer;
  4 import java.util.AbstractCollection;
  5 import java.util.AbstractSet;
  6 import java.util.HashMap;
  7 import java.util.Iterator;
  8 import java.util.Map;
  9 import java.util.Set;
 10 import java.util.function.BiConsumer;
 11 import java.util.function.BiFunction;
 12 import java.io.IOException;
 13
 14 /**
 15  * <p>Hash table and linked list implementation of the <tt>Map</tt> interface,
 16  * with predictable iteration order.  This implementation differs from
 17  * <tt>HashMap</tt> in that it maintains a doubly-linked list running through
 18  * all of its entries.  This linked list defines the iteration ordering,
 19  * which is normally the order in which keys were inserted into the map
 20  * (<i>insertion-order</i>).  Note that insertion order is not affected
 21  * if a key is <i>re-inserted</i> into the map.  (A key <tt>k</tt> is
 22  * reinserted into a map <tt>m</tt> if <tt>m.put(k, v)</tt> is invoked when
 23  * <tt>m.containsKey(k)</tt> would return <tt>true</tt> immediately prior to
 24  * the invocation.)
 25  *  Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与HashMap的不同之处在于,
 26     后者维护着一个运行于所有条目的双重链接列表。
 27     此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。
 28     注意,如果在映射中重新插入键,则插入顺序不受影响。会按照第一次插入的顺序,再次插入到之前的位置
 29    (如果在调用m.put(k,v) 前 m.containsKey(k) 返回了true,则调用时会将键k重新插入到映射m中)
 30  * <p>This implementation spares its clients from the unspecified, generally
 31  * chaotic ordering provided by {@link HashMap} (and {@link Hashtable}),
 32  * without incurring the increased cost associated with {@link TreeMap}.  It
 33  * can be used to produce a copy of a map that has the same order as the
 34  * original, regardless of the original map‘s implementation:
 35    此实现可以让客户避免未指定的、由 HashMap(及 Hashtable)所提供的通常为杂乱无章的排序工作,同时无需增加与 TreeMap 相关的成本。             使用它可以生成一个与原来顺序相同的映射副本,而与原映射的实现无关:
 36  * <pre>
 37  *     void foo(Map m) {
 38  *         Map copy = new LinkedHashMap(m);
 39  *         ...
 40  *     }
 41  * </pre>
 42  * This technique is particularly useful if a module takes a map on input,
 43  * copies it, and later returns results whose order is determined by that of
 44  * the copy.  (Clients generally appreciate having things returned in the same
 45  * order they were presented.)
 46  * 如果模块通过输入得到一个映射,复制这个映射,然后返回由此副本确定其顺序的结果,这种情况下这项技术特别有用。
 47  (客户通常期望返回的内容与其出现的顺序相同。) 原样返回
 48  * <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
 49  * provided to create a linked hash map whose order of iteration is the order
 50  * in which its entries were last accessed, from least-recently accessed to
 51  * most-recently (<i>access-order</i>).  This kind of map is well-suited to
 52  * building LRU caches.  Invoking the {@code put}, {@code putIfAbsent},
 53  * {@code get}, {@code getOrDefault}, {@code compute}, {@code computeIfAbsent},
 54  * {@code computeIfPresent}, or {@code merge} methods results
 55  * in an access to the corresponding entry (assuming it exists after the
 56  * invocation completes). The {@code replace} methods only result in an access
 57  * of the entry if the value is replaced.  The {@code putAll} method generates one
 58  * entry access for each mapping in the specified map, in the order that
 59  * key-value mappings are provided by the specified map‘s entry set iterator.
 60  * <i>No other methods generate entry accesses.</i>  In particular, operations
 61  * on collection-views do <i>not</i> affect the order of iteration of the
 62  * backing map.
 63  提供特殊的构造方法来创建链接哈希映射,该哈希映射的迭代顺序就是最后访问其条目的顺序,
 64  从近期访问最少到近期访问最多的顺序(访问顺序)。这种映射很适合构建 LRU 缓存。调用put或get 方法将会访问相应的条目(假定调用完成后它还存在)。     putAll 方法以指定映射的条目集迭代器提供的键-值映射关系的顺序,为指定映射的每个映射关系生成一个条目访问。
 65  任何其他方法均不生成条目访问。特别是,collection 视图上的操作不 影响底层映射的迭代顺序
 66  *
 67  * <p>The {@link #removeEldestEntry(Map.Entry)} method may be overridden to
 68  * impose a policy for removing stale mappings automatically when new mappings
 69  * are added to the map.
 70  可以重写 removeEldestEntry(Map.Entry) 方法来实施策略,以便在将新映射关系添加到映射时自动移除旧的映射关系。
 71  * <p>This class provides all of the optional <tt>Map</tt> operations, and
 72  * permits null elements.  Like <tt>HashMap</tt>, it provides constant-time
 73  * performance for the basic operations (<tt>add</tt>, <tt>contains</tt> and
 74  * <tt>remove</tt>), assuming the hash function disperses elements
 75  * properly among the buckets.  Performance is likely to be just slightly
 76  * below that of <tt>HashMap</tt>, due to the added expense of maintaining the
 77  * linked list, with one exception: Iteration over the collection-views
 78  * of a <tt>LinkedHashMap</tt> requires time proportional to the <i>size</i>
 79  * of the map, regardless of its capacity.  Iteration over a <tt>HashMap</tt>
 80  * is likely to be more expensive, requiring time proportional to its
 81  * <i>capacity</i>.
 82  *此类提供所有可选的 Map 操作,并且允许 null 元素。与 HashMap 一样,
 83   它可以为基本操作(add、contains和remove)提供稳定的性能,假定哈希函数将元素正确分布到桶中。
 84   由于增加了维护链接列表的开支,其性能很可能比 HashMap 稍逊一筹,不过这一点例外:LinkedHashMap 的 collection 视图迭代所需时间与映射的大小成比例。      HashMap 迭代时间很可能开支较大,因为它所需要的时间与其容量 成比例。
 85  * <p>A linked hash map has two parameters that affect its performance:
 86  * <i>initial capacity</i> and <i>load factor</i>.  They are defined precisely
 87  * as for <tt>HashMap</tt>.  Note, however, that the penalty for choosing an
 88  * excessively high value for initial capacity is less severe for this class
 89  * than for <tt>HashMap</tt>, as iteration times for this class are unaffected
 90  * by capacity.
 91  *链接的哈希映射具有两个影响其性能的参数:初始容量和加载因子。它们的定义与 HashMap 极其相似。要注意,为初始容量选择非常高的值对此类的影响比对 HashMap 要小,      因为此类的迭代时间不受容量的影响。
 92  * <p><strong>Note that this implementation is not synchronized.</strong>
 93  * If multiple threads access a linked hash map concurrently, and at least
 94  * one of the threads modifies the map structurally, it <em>must</em> be
 95  * synchronized externally.  This is typically accomplished by
 96  * synchronizing on some object that naturally encapsulates the map.
 97  *
 98  * If no such object exists, the map should be "wrapped" using the
 99  * {@link Collections#synchronizedMap Collections.synchronizedMap}
100  * method.  This is best done at creation time, to prevent accidental
101  * unsynchronized access to the map:<pre>
102  *   Map m = Collections.synchronizedMap(new LinkedHashMap(...));</pre>
103  * 注意,此实现不是同步的。如果多个线程同时访问链接的哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步。       这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedMap 方法来“包装”该映射。最好在创建时完成这一操作,       以防止对映射的意外的非同步访问:
104  * A structural modification is any operation that adds or deletes one or more
105  * mappings or, in the case of access-ordered linked hash maps, affects
106  * iteration order.  In insertion-ordered linked hash maps, merely changing
107  * the value associated with a key that is already contained in the map is not
108  * a structural modification.  <strong>In access-ordered linked hash maps,
109  * merely querying the map with <tt>get</tt> is a structural modification.
110  * </strong>)
111  结构修改是指添加或删除一个或多个映射关系,或者在按访问顺序链接的哈希映射中影响迭代顺序的任何操作。
112  在按插入顺序链接的哈希映射中,仅更改与映射中已包含键关联的值不是结构修改。在按访问顺序链接的哈希映射中,仅利用 get 查询映射是结构修改。)1.6和1.8有区别
113  *当accessOrder为true时,在迭代器方式遍历map时,不允许使用get操作,因为在迭代器模式中不允许修改集合的结构,一般情况下get操作是只读的,      但是本模式下,get操作需要修改map的链表结构,以将最近访问的元素放置到链表末尾。
114
115  * <p>The iterators returned by the <tt>iterator</tt> method of the collections
116  * returned by all of this class‘s collection view methods are
117  * <em>fail-fast</em>: if the map is structurally modified at any time after
118  * the iterator is created, in any way except through the iterator‘s own
119  * <tt>remove</tt> method, the iterator will throw a {@link
120  * ConcurrentModificationException}.  Thus, in the face of concurrent
121  * modification, the iterator fails quickly and cleanly, rather than risking
122  * arbitrary, non-deterministic behavior at an undetermined time in the future.
123  *Collection(由此类的所有 collection 视图方法所返回)的 iterator 方法返回的迭代器都是快速失败 的:在迭代器创建之后,如果从结构上对映射进行修改,     除非通过迭代器自身的 remove方法,其他任何时间任何方式的修改,迭代器都将抛出ConcurrentModificationException。
124  因此,面对并发的修改,迭代器很快就会完全失败,
125  而不冒将来不确定的时间任意发生不确定行为的风险。
126  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
127  * as it is, generally speaking, impossible to make any hard guarantees in the
128  * presence of unsynchronized concurrent modification.  Fail-fast iterators
129  * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
130  * Therefore, it would be wrong to write a program that depended on this
131  * exception for its correctness:   <i>the fail-fast behavior of iterators
132  * should be used only to detect bugs.</i>
133  *注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。
134   快速失败迭代器会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,
135   正确做法是:迭代器的快速失败行为应该仅用于检测程序错误
136
137  *
138  * <p>This class is a member of the
139  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
140  * Java Collections Framework</a>.
141  *
142  * @implNote
143  * The spliterators returned by the spliterator method of the collections
144  * returned by all of this class‘s collection view methods are created from
145  * the iterators of the corresponding collections.
146  *
147  * @param <K> the type of keys maintained by this map
148  * @param <V> the type of mapped values
149  *
150  * @author  Josh Bloch
151  * @see     Object#hashCode()
152  * @see     Collection
153  * @see     Map
154  * @see     HashMap
155  * @see     TreeMap
156  * @see     Hashtable
157  * @since   1.4
158  */
159
160 public class LinkedHashMap<K,V>
161     extends HashMap<K,V>
162     implements Map<K,V>
163 {
164
165     private static final long serialVersionUID = 3801124242820219131L;
166
167     /**
168      * The head of the doubly linked list.
169      * 双向链表的头
170      */
171     private transient Entry<K,V> header;
172
173     /**
174      * The iteration ordering method for this linked hash map: <tt>true</tt>
175      * for access-order, <tt>false</tt> for insertion-order.
176      * LinkedHashMap 迭代的排序方法 当为True时,表示按访问顺序排序
177        当为false时,表示按插入顺序排序,默认是按插入顺序排序
178      * @serial
179      */
180     private final boolean accessOrder;
181
182     /**
183      * Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
184      * with the specified initial capacity and load factor.
185      * 构造一个空的按插入顺序排序的LinkedHashMap,并指定初始化容量和负载因子,调用父类的构造器构造
186      * @param  initialCapacity the initial capacity
187      * @param  loadFactor      the load factor
188      * @throws IllegalArgumentException if the initial capacity is negative
189      *         or the load factor is nonpositive
190      */
191     public LinkedHashMap(int initialCapacity, float loadFactor) {
192         super(initialCapacity, loadFactor);
193         accessOrder = false;
194     }
195
196     /**
197      * Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
198      * with the specified initial capacity and a default load factor (0.75).
199      * 构造一个空的按插入顺序排序的LinkedHashMap,并指定初始化容量和默认的负载因子0.75,调用父类的构造器构造
200      * @param  initialCapacity the initial capacity
201      * @throws IllegalArgumentException if the initial capacity is negative
202      */
203     public LinkedHashMap(int initialCapacity) {
204     super(initialCapacity);
205         accessOrder = false;
206     }
207
208     /**
209      * Constructs an empty insertion-ordered <tt>LinkedHashMap</tt> instance
210      * with the default initial capacity (16) and load factor (0.75).
211      构造一个空的按插入顺序排序的LinkedHashMap,并指定默认初始化容量16和默认的负载因子0.75,调用父类的构造器构造
212      */
213     public LinkedHashMap() {
214     super();
215         accessOrder = false;
216     }
217
218     /**
219      * Constructs an insertion-ordered <tt>LinkedHashMap</tt> instance with
220      * the same mappings as the specified map.  The <tt>LinkedHashMap</tt>
221      * instance is created with a default load factor (0.75) and an initial
222      * capacity sufficient to hold the mappings in the specified map.
223      * 用指定的Map构造一个按插入顺序排序的LinkedHashMap,默认的负载因子0.75和足够容纳给定map的初始化容量
224      * @param  m the map whose mappings are to be placed in this map
225      * @throws NullPointerException if the specified map is null
226      */
227     public LinkedHashMap(Map<? extends K, ? extends V> m) {
228         super(m);
229         accessOrder = false;
230     }
231
232     /**
233      * Constructs an empty <tt>LinkedHashMap</tt> instance with the
234      * specified initial capacity, load factor and ordering mode.
235      * 构造一个空的按插入顺序排序的LinkedHashMap,并指定初始化容量,负载因子和排序方式
236      * @param  initialCapacity the initial capacity
237      * @param  loadFactor      the load factor
238      * @param  accessOrder     the ordering mode - <tt>true</tt> for
239      *         access-order, <tt>false</tt> for insertion-order
240      * @throws IllegalArgumentException if the initial capacity is negative
241      *         or the load factor is nonpositive
242      */
243     public LinkedHashMap(int initialCapacity,
244              float loadFactor,
245                          boolean accessOrder) {
246         super(initialCapacity, loadFactor);
247         this.accessOrder = accessOrder;
248     }
249
250     /**
251      * Called by superclass constructors and pseudoconstructors (clone,
252      * readObject) before any entries are inserted into the map.  Initializes
253      * the chain.
254        覆写父类的init方法,在父类中都是空方法,在任何键值对被放入map之前在父类的构造器和伪构造器中调用
255        初始化双向链表,初始化一个空的节点,hashcode的值是-1,并不存放在哈希表中,作为双向循环链表的头部,
256        循环的开始节点或者可以认为也是结束的标志
257      */
258     void init() {
259         header = new Entry<K,V>(-1, null, null, null);
260         header.before = header.after = header;
261     }
262
263     /**
264      * Transfers all entries to new table array.  This method is called
265      * by superclass resize.  It is overridden for performance, as it is
266      * faster to iterate using our linked list.
267        将所有的键值对复制到新的哈希表中,该方法在父类的扩容被调用
268        该方法被重写是因为他的性能,因为我们用维护的链表遍历速度更快
269      */
270     void transfer(HashMap.Entry[] newTable) {
271         int newCapacity = newTable.length;
272         for (Entry<K,V> e = header.after; e != header; e = e.after) {
273             int index = indexFor(e.hash, newCapacity);
274             e.next = newTable[index];
275             newTable[index] = e;
276         }
277     }
278
279
280     /**
281      * Returns <tt>true</tt> if this map maps one or more keys to the
282      * specified value.
283      *
284      * @param value value whose presence in this map is to be tested
285      * @return <tt>true</tt> if this map maps one or more keys to the
286      *         specified value
287      */
288     public boolean containsValue(Object value) {
289         // Overridden to take advantage of faster iterator
290         //重写是为了性能,链表的遍历速度更快
291         if (value==null) {
292             for (Entry e = header.after; e != header; e = e.after)
293                 if (e.value==null)
294                     return true;
295         } else {
296             for (Entry e = header.after; e != header; e = e.after)
297                 if (value.equals(e.value))
298                     return true;
299         }
300         return false;
301     }
302
303     /**
304      * Returns the value to which the specified key is mapped,
305      * or {@code null} if this map contains no mapping for the key.
306      * 根据指定的Map的Key返回value值,如果没有返回null,也可能是key对于的Value就是null
307      * <p>More formally, if this map contains a mapping from a key
308      * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
309      * key.equals(k))}, then this method returns {@code v}; otherwise
310      * it returns {@code null}.  (There can be at most one such mapping.)
311      * 更正式点说,如果存在这样个map(key==null ? k==null : key.equals(k)
312      * 返回value,否则返回null,最多只有一个这个的键值对
313      * <p>A return value of {@code null} does not <i>necessarily</i>
314      * indicate that the map contains no mapping for the key; it‘s also
315      * possible that the map explicitly maps the key to {@code null}.
316      * The {@link #containsKey containsKey} operation may be used to
317      * distinguish these two cases.
318      并不一定会返回null,如果返回null值,表示不存在指定key的map,或者可能是该key的Value就是null
319      可以通过containsKey操作来判别
320      */
321     public V get(Object key) {
322         Entry<K,V> e = (Entry<K,V>)getEntry(key);
323         if (e == null)
324             return null;
325         e.recordAccess(this);
326         return e.value;
327     }
328
329     /**
330      * Removes all of the mappings from this map.
331      * The map will be empty after this call returns.
332        删除所有键值对
333      */
334     public void clear() {
335         super.clear();
336         header.before = header.after = header;
337     }
338
339     /**
340      * LinkedHashMap entry.
341        LinkedHashMap的键值对对象,继承了HashMap的属性hash,key,value,next,并且新增属性 before和after,前四个属性是为了维护哈希表,before和after属性是为了维护双向循环链表
342      */
343     private static class Entry<K,V> extends HashMap.Entry<K,V> {
344         // These fields comprise the doubly linked list used for iteration.
345         //用来对双向循环链表进行遍历
346         Entry<K,V> before, after;
347
348     Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
349             super(hash, key, value, next);
350         }
351
352         /**
353          * Removes this entry from the linked list.
354            从双向链表中移除当前节点
355          */
356         private void remove() {
357             before.after = after;
358             after.before = before;
359         }
360
361         /**
362          * Inserts this entry before the specified existing entry in the list.
363            在已存在的双向链表中的某个节点之前,插入当前节点
364          */
365         private void addBefore(Entry<K,V> existingEntry) {
366             after  = existingEntry;
367             before = existingEntry.before;
368             before.after = this;
369             after.before = this;
370         }
371
372         /**
373          * This method is invoked by the superclass whenever the value
374          * of a pre-existing entry is read by Map.get or modified by Map.set.
375            该方法在父类中通过Map.get获取或者通过Map.set修改已经存在的键值对
376          * If the enclosing Map is access-ordered, it moves the entry
377          * to the end of the list; otherwise, it does nothing.
378            如果封装的Map是访问排序的,该方法会将当前的键值对移到链表的结尾,其他情况,什么也不做
379          */
380         void recordAccess(HashMap<K,V> m) {
381             LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
382             if (lm.accessOrder) {
383                 lm.modCount++;
384                 remove();
385                 addBefore(lm.header);
386             }
387         }
388          //从链表中移除当前键值对
389         void recordRemoval(HashMap<K,V> m) {
390             remove();
391         }
392     }
393     //实现迭代器,不多说
394     private abstract class LinkedHashIterator<T> implements Iterator<T> {
395     Entry<K,V> nextEntry    = header.after;
396     Entry<K,V> lastReturned = null;
397
398     /**
399      * The modCount value that the iterator believes that the backing
400      * List should have.  If this expectation is violated, the iterator
401      * has detected concurrent modification.
402      */
403     int expectedModCount = modCount;
404
405     public boolean hasNext() {
406             return nextEntry != header;
407     }
408
409     public void remove() {
410         if (lastReturned == null)
411         throw new IllegalStateException();
412         if (modCount != expectedModCount)
413         throw new ConcurrentModificationException();
414
415             LinkedHashMap.this.remove(lastReturned.key);
416             lastReturned = null;
417             expectedModCount = modCount;
418     }
419
420     Entry<K,V> nextEntry() {
421         if (modCount != expectedModCount)
422         throw new ConcurrentModificationException();
423             if (nextEntry == header)
424                 throw new NoSuchElementException();
425
426             Entry<K,V> e = lastReturned = nextEntry;
427             nextEntry = e.after;
428             return e;
429     }
430     }
431
432     private class KeyIterator extends LinkedHashIterator<K> {
433     public K next() { return nextEntry().getKey(); }
434     }
435
436     private class ValueIterator extends LinkedHashIterator<V> {
437     public V next() { return nextEntry().value; }
438     }
439
440     private class EntryIterator extends LinkedHashIterator<Map.Entry<K,V>> {
441     public Map.Entry<K,V> next() { return nextEntry(); }
442     }
443
444     // These Overrides alter the behavior of superclass view iterator() methods
445     Iterator<K> newKeyIterator()   { return new KeyIterator();   }
446     Iterator<V> newValueIterator() { return new ValueIterator(); }
447     Iterator<Map.Entry<K,V>> newEntryIterator() { return new EntryIterator(); }
448
449     /**
450      * This override alters behavior of superclass put method. It causes newly
451      * allocated entry to get inserted at the end of the linked list and
452      * removes the eldest entry if appropriate.
453        修改父类的put方法,最近放入的键值对,放在链表的尾部,如果条件允许删除最不经常使用的元素,也就是
454        在访问排序的模式下,链表最前面的那一个元素
455      */
456     void addEntry(int hash, K key, V value, int bucketIndex) {
457         createEntry(hash, key, value, bucketIndex);
458
459         // Remove eldest entry if instructed, else grow capacity if appropriate
460         //如果被允许,删除最不常用的键值对,否则,就进行扩容
461         Entry<K,V> eldest = header.after;
462         if (removeEldestEntry(eldest)) {
463             removeEntryForKey(eldest.key);
464         } else {
465             if (size >= threshold)
466                 resize(2 * table.length);
467         }
468     }
469
470     /**
471      * This override differs from addEntry in that it doesn‘t resize the
472      * table or remove the eldest entry.
473        这重写与addEntry,因为不用扩容和删除最不常用的节点
474      */
475     void createEntry(int hash, K key, V value, int bucketIndex) {
476         HashMap.Entry<K,V> old = table[bucketIndex];
477     Entry<K,V> e = new Entry<K,V>(hash, key, value, old);
478         table[bucketIndex] = e;
479         //将新增的键值对放到链表的尾部
480         e.addBefore(header);
481         size++;
482     }
483
484     /**
485      * Returns <tt>true</tt> if this map should remove its eldest entry.
486      * This method is invoked by <tt>put</tt> and <tt>putAll</tt> after
487      * inserting a new entry into the map.  It provides the implementor
488      * with the opportunity to remove the eldest entry each time a new one
489      * is added.  This is useful if the map represents a cache: it allows
490      * the map to reduce memory consumption by deleting stale entries.
491      * 该方法为了是先LRU(Least Recently Used)缓存
492      * <p>Sample use: this override will allow the map to grow up to 100
493      * entries and then delete the eldest entry each time a new entry is
494      * added, maintaining a steady state of 100 entries.
495      * <pre>
496      *     private static final int MAX_ENTRIES = 100;
497      *
498      *     protected boolean removeEldestEntry(Map.Entry eldest) {
499      *        return size() > MAX_ENTRIES;
500      *     }
501      * </pre>
502      *
503      * <p>This method typically does not modify the map in any way,
504      * instead allowing the map to modify itself as directed by its
505      * return value.  It <i>is</i> permitted for this method to modify
506      * the map directly, but if it does so, it <i>must</i> return
507      * <tt>false</tt> (indicating that the map should not attempt any
508      * further modification).  The effects of returning <tt>true</tt>
509      * after modifying the map from within this method are unspecified.
510      *
511      * <p>This implementation merely returns <tt>false</tt> (so that this
512      * map acts like a normal map - the eldest element is never removed).
513      *
514      * @param    eldest The least recently inserted entry in the map, or if
515      *           this is an access-ordered map, the least recently accessed
516      *           entry.  This is the entry that will be removed it this
517      *           method returns <tt>true</tt>.  If the map was empty prior
518      *           to the <tt>put</tt> or <tt>putAll</tt> invocation resulting
519      *           in this invocation, this will be the entry that was just
520      *           inserted; in other words, if the map contains a single
521      *           entry, the eldest entry is also the newest.
522      * @return   <tt>true</tt> if the eldest entry should be removed
523      *           from the map; <tt>false</tt> if it should be retained.
524      */
525     protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
526         return false;
527     }
528 }

参考链接 http://blog.csdn.net/ns_code/article/details/37867985         https://www.cnblogs.com/xiaoxi/p/6170590.html

时间: 2024-10-25 08:12:49

java源码解析---LinkedHashMap的相关文章

深入Java源码解析容器类List、Set、Map

1 常用容器继承关系图先上一张网上的继承关系图个人觉得有些地方不是很准确,比如Iterator不是容器,只是一个操作遍历集合的方法接口,所以不应该放在里面.并且Map不应该继承自Collection.所以自己整理了一个常用继承关系图如下如上图所示,接下去会自顶向下解释重要的接口和实现类.2 Collection和Map在Java容器中一共定义了2种集合, 顶层接口分别是Collection和Map.但是这2个接口都不能直接被实现使用,分别代表两种不同类型的容器.简单来看,Collection代表

Java源码解析——集合框架(二)——ArrayBlockingQueue

ArrayBlockingQueue源码解析 ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection接口.底层以数组的形式保存数据(实际上可看作一个循环数组).常用的操作包括 add ,offer,put,remove,poll,take,peek. 一.类声明 public class ArrayBlockingQueue<E> extends AbstractQueue<E> i

Java源码解析 - ThreadPoolExecutor 线程池

1 线程池的好处 线程使应用能够更加充分合理地协调利用CPU.内存.网络.I/O等系统资源.线程的创建需要开辟虚拟机栈.本地方法栈.程序计数器等线程私有的内存空间;在线程销毁时需要回收这些系统资源.频繁地创建和销毁线程会浪费大量的系统资源,增加并发编程风险. 在服务器负载过大的时候,如何让新的线程等待或者友好地拒绝服务? 这些都是线程自身无法解决的;所以需要通过线程池协调多个线程,并实现类似主次线程隔离.定时执行.周期执行等任务. 线程池的作用包括:●利用线程池管理并复用线程.控制最大并发数等●

[java源码解析]对HashMap源码的分析(二)

上文我们讲了HashMap那骚骚的逻辑结构,这一篇我们来吹吹它的实现思想,也就是算法层面.有兴趣看下或者回顾上一篇HashMap逻辑层面的,可以看下HashMap源码解析(一).使用了哈希表得"拉链法". 我打算按这个顺序来讲HashMap:几个关键属性 -> 构造方法-> 存取元素方法 ->解决hash冲突方法->HashMap扩容问题. 4个关键属性: /** *HashMap的存储大小 */ transient int size; /** * HashMa

【Java源码解析】-- HashMap源码解析

目录 源码解析 1.构造方法 无参构造方法 int型参数的构造方法 int,float两个参数的构造方法 hsah方法 2.添加元素(put()方法) 3.扩容方法(resize()方法) 4.获取元素(get()方法) 5.移除元素(remove()) 6.树化(treeifyBin()) 关于HashMap常见的问题 1.为什么容量始终是2的幂次? 3.既然红黑树那么好,为啥hashmap不直接采用红黑树,而是当大于等于8个的时候才转换红黑树? 4.JDK1.7 扩容死锁产生原因 5.JDK

Java源码解析之HashMap

一.HashMap类声明: HashMap继承于AbstractMap并且实现了接口Map,Cloneable,Serializable. public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {} 二.HashMap类层次: HashMap实现了三个接口,继承一个抽象类.除此之外我们应该知道Object是所有类的超类.之所以有一个A

Java源码解析|HashMap的前世今生

HashMap的前世今生 Java8在Java7的基础上,做了一些改进和优化. 底层数据结构和实现方法上,HashMap几乎重写了一套 所有的集合都新增了函数式的方法,比如说forEach,也新增了很多好用的函数. 前世--Java 1.7 底层数据结构 数组 + 链表 在Java1.7中HashMap使用数组+链表来作为存储结构 数组就类似一个个桶构成的容器,链表用来解决冲突,当出现冲突时,就找到当前数据应该存储的桶的位置(数组下标),在当前桶中插入新链表结点. 如下图所示: 链表结点中存放(

JDK核心JAVA源码解析(1) - Object

想写这个系列很久了,对自己也是个总结与提高.原来在学JAVA时,那些JAVA入门书籍会告诉你一些规律还有法则,但是用的时候我们一般很难想起来,因为我们用的少并且不知道为什么.知其所以然方能印象深刻并学以致用. 首先我们从所有类的父类Object开始: 1. Object类 (1)hashCode方法和equals方法 public native int hashCode(); public boolean equals(Object obj) { return (this == obj); }

Java源码解析|String源码与常用方法

String源码与常用方法 1.栗子 代码: public class JavaStringClass { public static void main(String[] args) { String s ="hello"; s = "world"; //内存地址已经修改 原来地址上的值还是不变的 String s2 = "hello"; //从常量值中找到并引用 String s4 = new String("hello"