//linkedHashMap中的init()方法,就使用header,hash值为-1,其他度为null,也就是说这个header不放在数组中,就是用来指示开始元素和标志结束元素的。 void init() { header = new Entry<>(-1, null, null, null); //一开始是自己指向自己,没有任何元素。HashMap中也有init()方法是个空的,所以这里的init()方法就是为LinkedHashMap而写的。 header.before = header.after = header; } //在HashMap的构造方法中就会使用到init(), public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); this.loadFactor = loadFactor; threshold = initialCapacity; init(); }
2.4、LinkedHashMap是如何和其父类HashMap共享一些方法的。比如,put操作等。
1、LinkedHashMap构造方法完成后,调用put往其中添加元素,查看父类中的put源码
put
1 //这个方法应该挺熟悉的,如果看了HashMap的解析的话 2 public V put(K key, V value) { 3 //刚开始其存储空间啥也没有,在这里初始化 4 if (table == EMPTY_TABLE) { 5 inflateTable(threshold); 6 } 7 //key为null的情况 8 if (key == null) 9 return putForNullKey(value); 10 //通过key算hash,进而算出在数组中的位置,也就是在第几个桶中 11 int hash = hash(key); 12 int i = indexFor(hash, table.length); 13 //查看桶中是否有相同的key值,如果有就直接用新植替换旧值,而不用在创建新的entry了 14 for (Entry<K,V> e = table[i]; e != null; e = e.next) { 15 Object k; 16 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 17 V oldValue = e.value; 18 e.value = value; 19 e.recordAccess(this); 20 return oldValue; 21 } 22 } 23 24 modCount++; 25 //上面度是熟悉的东西,最重要的地方来了,就是这个方法,LinkedHashMap执行到这里,addEntry()方法不会执行HashMap中的方法,而是执行自己类中的addEntry方法,这里就要 提一下LinkedHashMap重写HashMap中两个个关键的方法了。看下面的分析。 26 addEntry(hash, key, value, i); 27 return null; 28 }
重写了void addEntry(int hash, K key, V value, int bucketIndex) 和void createEntry(int hash, K key, V value, int bucketIndex)