LinkedHashMap is similar to a HashMap, but when iteratively traversing it, the order in which "key-value pairs" are obtained is the insertion order, or the least recently used (LRU) Order. It is only a little slower than HashMap, but faster during iterative access, because it uses the linked list to maintain the internal order (HashMap is implemented based on the hash list, for details about HashMap, see Java Collection class and HashMap source code analysis.) 1 public class extends HashMap <K, V> extends HashMap <K, V> implements Map <K, V> extends HashMap inherited from HashMap and implemented the Map interface. LinkedHashMap only defines two attributes: 1/** 2 * The head of the doubly linked list. 3 * header node 4 */5 private transient Entry <K, V> header; 6/** 7 * The iteration ordering method for this linked hash map: true 8 * for access-order, false for insertion-order. 9 * true indicates the minimum recently used order, and false indicates the insert Order 10 */www.2cto. com11 private final boolean accessOrder; Consumer list provides a total of five constructor methods: 1 // constructor 1, which constructs a sort list with specified initial capacity and load factor in the order of insertion 2 public writable hashmap (int initialCapacity, float loadFactor) {3 super (initialCapacity, loadFactor); 4 accessOrder = false; 5} 6 // constructor 2, construct a LinkedHashMap with a specified initial capacity. The key-value pair is obtained by inserting the sequence 7 public LinkedHashMap (int initialCapacity) {8 super (initialCapacity); 9 accessOrder = false; 10} 11 // constructor 3. Create a LinkedHashMap with the default initial capacity and load factor to obtain the key-value pairs in the order of 12 public synchronized hashmap () {13 super (); 14 accessOrder = false; 15} 1 6 // constructor 4: Create a LinkedHashMap using the input map. The capacity is the default capacity (16) and (map. if zise ()/DEFAULT_LOAD_FACTORY) + 1 is large, the load factor is 17 by default public writable hashmap (Map <? Extends K ,? Extends V> m) {18 super (m); 19 accessOrder = false; 20} 21 // constructor 5, create a LinkedHashMap22 public LinkedHashMap (int initialCapacity, 23 float loadFactor, 24 boolean accessOrder) {25 super (initialCapacity, loadFactor) in sequence based on the specified capacity, load factor, and key-value pairs ); 26 this. accessOrder = accessOrder; 27} we can see from the constructor that the insertion order is used by default to maintain the order of key-value pairs. All constructor Methods create objects by calling the constructor of the parent class. LinkedHashMap is based on a two-way linked list, and a header node is set in the attribute. Why didn't the constructor initialize it? Note that there is an init () method in LinkedHashMap. The construction methods of HashMap call the init () method, here, the LinkedHashMap constructor calls the init () method from the parent constructor after calling the parent class Constructor (This also explains why there is a non-content init () in HashMap () method ). 1 void init () {2 header = new Entry <K, V> (-1, null); 3 header. before = header. after = header; 4} according to the init () method, the header is indeed initialized and constructed into a bidirectional cyclic linked list (the same as the storage structure of the sorted list ). The transfer (HashMap. Entry [] newTable) method and the init () method are also called in HashTable. The transfer (HashMap. Entry [] newTable) method is called when HashMap calls the resize (int newCapacity) method. 1 void transfer (HashMap. Entry [] newTable) {2 int newCapacity = newTable. length; 3 for (Entry <K, V> e = header. after; e! = Header; e = e. after) {4 int index = indexFor (e. hash, newCapacity); 5 e. next = newTable [index]; 6 newTable [index] = e; 7} 8} calculate the index of e in the table array of the new capacity based on the hash value of linked list node e, insert e into the linked list referenced by the calculated index. ContainsValue (Object value) 1 public boolean containsValue (Object value) {2 // Overridden to take advantage of faster iterator 3 if (value = null) {4 for (Entry e = header. after; e! = Header; e = e. after) 5 if (e. value = null) 6 return true; 7} else {8 for (Entry e = header. after; e! = Header; e = e. after) 9 if (value. equals (e. value) 10 return true; 11} 12 return false; 13} rewrite the insvalue (Object value) method of the parent class and use the header traversal table to determine whether the value is equal to the value, instead of querying the table array. Get (Object key) 1 public V get (Object key) {2 Entry <K, V> e = (Entry <K, V>) getEntry (key ); 3 if (e = null) 4 return null; 5 e. recordAccess (this); 6 return e. value; 7} The get (Object key) method obtains the node through the getEntry (Object key) method of HashMap and returns the value of the node. If the node is null, null is returned. RecordAccess (HashMap <K, V> m) is a method of Entry class in LinkedHashMap. It will be detailed when introducing the Entry. Clear () 1 public void clear () {2 super. clear (); 3 header. before = header. after = header; 4} the clear () method first calls the clear () method of the parent class, and then points the before and after references of the header nodes of the linked list to the header itself, that is, the header node is a two-way circular linked list. In this way, the remaining nodes in the original linked list cannot be accessed, and they will be recycled by GC. The above content involves more or less the internal class Entry <K, V> of LinkedHashMap. The following describes the internal class in detail. 1 // This is a private, static internal class that inherits from the HashMap Entry. 2 private static class Entry <K, V> extends HashMap. entry <K, V> {3 // reference of the front and back nodes 4 Entry <K, V> before, after; 5 // The constructor directly calls the constructor of the parent class 6 Entry (int hash, K key, V value, HashMap. entry <K, V> next) {7 super (hash, key, value, next); 8} 9 10 // remove the node, you only need to modify the after reference of the previous node and the before reference of the next node 11 private void remove () {12 // after modification, the node service will be accessed and 13 before will be reclaimed by GC. after = after; 14 after. before = before; 15} 16 17 // Insert the current node before the specified node (bidirectional linked list insertion) 18 private void addBefore (Entry <K, V> existingEntry) {19 // point the after reference of the current node to existingEntry20 after = existingEntry; 21 // point the before reference to the previous node 22 before = existingEntry of the existingEntry node. before; 23 // point the after reference of the previous existingEntry node to the current node 24 before. after = this; 25 // point the before reference of the last node of the original existingEntry node to the current node 26 after. before = this; 27} 28 29 // when the get or put method of this class is called (the put method will call the HashMap of the parent class. the put30 // method of the Entry) will be called to rec OrdAccess (HashMap <K, V> m) method 31 // If the accessOrder is true, the minimum recently used order is used, the modified 32 // node is moved to the end of the linked list before the header node. 33 // That's why HashMap. the Entry contains an empty 34 // reason for the recordAccess (HashMap <K, V> m) Method 35 void recordAccess (HashMap <K, V> m) {36 LinkedHashMap <K, v> lm = (LinkedHashMap <K, V>) m; 37 if (lm. accessOrder) {38 lm. modCount ++; 39 remove (); 40 addBefore (lm. header); 41} 42} 43 // and recordAccess (HashMap <K. v> m) Same method, in HashMap. there is also a corresponding empty method in the Entry. When the delete operation is performed, the system will call 44 void recordRemoval (HashMap <K, V> m) {45 remove (); 46} 47} to describe the internal class Entry, the following two methods are used to create an Entry node and add an Entry. CreateEntry (int hash, K key, V value, int bucketIndex) 1 void createEntry (int hash, K key, V value, int bucketIndex) {2 HashMap. entry <K, V> old = table [bucketIndex]; 3 Entry <K, V> e = new Entry <K, V> (hash, key, value, old ); 4 table [bucketIndex] = e; 5 e. addBefore (header); 6 size ++; 7} The createEntry (int hash, K key, V value, int bucketIndex) method overwrites the methods in the parent HashMap class. This method does not expand the size of the table array. This method first retains the nodes at the bucketIndex In the table, and then calls the Entry Constructor (it will call the HashMap of the parent class. add a node to point the next reference of the current node to the node of table [bucketIndex], and then call the e. addBefore (header) is to modify the linked list and add the e node before the header node. This method also adds nodes to the table [bucketIndex] linked list, and also to the LinkedHashMap own linked list. AddEntry (int hash, K key, V value, int bucketIndex) 1 void addEntry (int hash, K key, V value, int bucketIndex) {2 createEntry (hash, key, value, bucketIndex); 3 Entry <K, V> eldest = header. after; 4 if (removeEldestEntry (eldest) {5 removeEntryForKey (eldest. key); 6} else {7 if (size> = threshold) 8 resize (2 * table. length); 9} 10} First call the createEntry (int hash, K key, V value, int bucketIndex) method, and then obtain Lin The "Oldest" (least recently used) node in kedHashMap involves the removeEldestEntry (Entry <K, V> eldest) method. Let's take a look: 1 protected boolean removeEldestEntry (Map. entry <K, V> eldest) {2 return false; 3} Why does this method always return false? Combined with the above addEntry (int hash, K key, V value, int bucketIndex) method, this design can make the LinkedHashMap a normal Map without removing the "Oldest" node. Why is this logic not directly removed from the Code but designed like this? This provides convenience for developers. If you want to use Map as a Cache and limit the size, you only need to inherit LinkedHashMap and override the removeEldestEntry (Entry <K, V> eldest) method, like this: 1 private static final int MAX_ENTRIES = 100; 2 protected boolean removeEldestEntry (Map. entry eldest) {3 return size ()> MAX_ENTRIES; 4} In addition to the preceding content, LinkedHashMap has three iteration-related methods, three internal classes, and an abstract internal class, newKeyIterator (), newValueIterator (), newEntryIterator (), KeyIterator, ValueIterator, EntryIterator, and LinkedHashIte Rator class. The three new methods return instances of the corresponding three classes. The three classes are inherited from the abstract class LinkedHashIterator. The following describes three types of iteration. 1 private class KeyIterator extends hashiterator <K> {2 public K next () {return nextEntry (). getKey () ;}3} 4 private class ValueIterator extends hashiterator <V> {5 public V next () {return nextEntry (). value;} 6} 7 private class EntryIterator extends hashiterator <Map. entry <K, V> {8 public Map. entry <K, V> next () {return nextEntry ();} 9} From the above we can see that these three classes are very simple, there is only one next () method, next () the method is just to call Li The method in the nkedHashIterator class. And KeyIterator class, ValueIterator class, EntryIterator class, And javashashiterator class. The following is the content of the LinkedHashIterator class. 1 private abstract class extends hashiterator <T> implements Iterator <T> {2 Entry <K, V> nextEntry = header. after; 3 Entry <K, V> lastReturned = null; 4 // The ListItr class in the Response List defines the same use of expectedModCount as 5 int expectedModCount = modCount; 6 // if the next node is a header node, it indicates that the current node is the last node of the linked list, that is, the linked list has been traversed, and no other node is 7 public boolean hasNext () {8 return nextEntry! = Header; 9} 10 // remove the node lastReturned 11 public void remove () {12 if (lastReturned = null) 13 throw new IllegalStateException (); 14 if (modCount! = ExpectedModCount) 15 throw new ConcurrentModificationException (); 16 rows hashmap. this. remove (lastReturned. key); 17 lastReturned = null; 18 expectedModCount = modCount; 19} 20 // return the next node 21 Entry <K, V> nextEntry () {22 if (modCount! = ExpectedModCount) 23 throw new ConcurrentModificationException (); 24 if (nextEntry = header) 25 throw new NoSuchElementException (); 26 // obtain and record the returned node 27 Entry <K, v> e = lastReturned = nextEntry; 28 // Save the reference to the next node 29 nextEntry = e. after; 30 return e; 31} 32} LinkedHashMap should have been analyzed with HashMap and shortlist to compare their similarities and differences. To make up for this, we will briefly summarize some similarities and differences between them: HashMap uses a hash table to store data and uses a zipper to handle conflicts. LinkedHashMap inherits from HashMap and has a linked list to store data. There is no conflict. A two-way circular linked list is used in the same way as the javashashmap, But it stores simple data rather than "key-value pairs ". Therefore, HashMap and LinkedHashMap are Map, while sorted List is a List, which is essentially different from each other. Both LinkedList and LinkedHashMap can maintain the order of the content, but HashMap does not maintain the order.