LinkedHashMapの詳細
6387 ワード
LinkedHashMapには重要なデータがあります.
次に、ソースコードを見てみましょう.
LinkedHashMapはputメソッドを実装せず、HashMapのputメソッドのaddNewEntryを複写しています
ここでまとめることができる.データを追加します.配列内の対応するindexを見つけてから、チェーンテーブルの最後の位置にデータを配置します.双方向チェーンテーブルなのでheaderに置くのと同じです.prv 2.データを取得します.配列内の対応するindexを見つけてから、データが存在する場所を見つけます.読み取り順に並べ替えられている場合は、このノードを双方向チェーンテーブルの最後のビットに配置します(この特性では、LRUアルゴリズムを実装できます).
参照先:http://wiki.jikexueyuan.com/project/java-collection/linkedhashmap.html http://blog.csdn.net/ns_code/article/details/37867985
// LinkedEntry 。 , before after
static class LinkedEntry<K, V> extends HashMapEntry<K, V> {
LinkedEntry nxt;
LinkedEntry prv;
/** Create the header entry */
LinkedEntry() {
super(null, null, 0, null);
nxt = prv = this;
}
/** Create a normal entry */
LinkedEntry(K key, V value, int hash, HashMapEntry next,
LinkedEntry nxt, LinkedEntry prv) {
super(key, value, hash, next);
this.nxt = nxt;
this.prv = prv;
}
}
次に、ソースコードを見てみましょう.
public class LinkedHashMap<K, V> extends HashMap<K, V> {
// transient , , 。 , transient 。
transient LinkedEntry header;
/**
* True if access ordered, false if insertion ordered.
*/
private final boolean accessOrder;
// header prv , tail
@Override
void addNewEntry(K key, V value, int hash, int index) {
LinkedEntry header = this.header;
// Remove eldest entry if instructed to do so.
LinkedEntry eldest = header.nxt;
if (eldest != header && removeEldestEntry(eldest)) {
remove(eldest.key);
}
// Create new entry, link it on to list, and put it into table
LinkedEntry oldTail = header.prv;
LinkedEntry newTail = new LinkedEntry(
key, value, hash, table[index], header, oldTail);
table[index] = oldTail.nxt = header.prv = newTail;
}
// HashMap , accessOrder
@Override
public V get(Object key) {
/*
* This method is overridden to eliminate the need for a polymorphic
* invocation in superclass at the expense of code duplication.
*/
if (key == null) {
HashMapEntry e = entryForNullKey;
if (e == null)
return null;
if (accessOrder)
makeTail((LinkedEntry) e);
return e.value;
}
// Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
int hash = secondaryHash(key);
HashMapEntry[] tab = table;
for (HashMapEntry e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
// , e
if (accessOrder)
makeTail((LinkedEntry) e);
return e.value;
}
}
return null;
}
// e header
private void makeTail(LinkedEntry e) {
// e
e.prv.nxt = e.nxt;
e.nxt.prv = e.prv;
// e header
LinkedEntry header = this.header;
LinkedEntry oldTail = header.prv;
e.nxt = header;
e.prv = oldTail;
oldTail.nxt = header.prv = e;
modCount++;
}
}
LinkedHashMapはputメソッドを実装せず、HashMapのputメソッドのaddNewEntryを複写しています
ここでまとめることができる.データを追加します.配列内の対応するindexを見つけてから、チェーンテーブルの最後の位置にデータを配置します.双方向チェーンテーブルなのでheaderに置くのと同じです.prv 2.データを取得します.配列内の対応するindexを見つけてから、データが存在する場所を見つけます.読み取り順に並べ替えられている場合は、このノードを双方向チェーンテーブルの最後のビットに配置します(この特性では、LRUアルゴリズムを実装できます).
参照先:http://wiki.jikexueyuan.com/project/java-collection/linkedhashmap.html http://blog.csdn.net/ns_code/article/details/37867985