LinkedHashMap/Set?
package samples;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
public class TestTreeMap {
public static void main(String[] args) {
//true LRU
Map<String, String> map = new LinkedHashMap<String, String>(10,0.75f,true);
/* true , false ,
*
* !!!HashMap !!!
*/
//Map<String, String> map = new LinkedHashMap<String, String>();
map.put("1", "aa");
map.put("2", "bb");
map.put("3", "cc");
populateMap(map);
/*
* "2" "2"
*/
map.get("2");
populateMap(map);
map.get("3");
/*
* "3" "3"
*/
populateMap(map);
/*
* "4" "4" ( )
*/
map.put("4", "dd");
populateMap(map);
/*
* "1", "1" ( )
*/
map.put("1", "aa");
populateMap(map);
}
public static void populateMap(Map<String, String> map) {
System.out.println("------------>");
Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, String> entry = iter.next();
System.out.print(entry.getKey() + " ");
System.out.println(entry.getValue());
}
}
}
====================================================================
HashMap:
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
final int hash;
Entry<K,V> next; //
LinkedHashMap:
private static class Entry<K,V> extends HashMap.Entry<K,V> {
// These fields comprise the doubly linked list used for iteration.
Entry<K,V> before, after; //
( ,
Linked hashMap , Entry<K,V> next
, , before,after
)
=============================================================
From API
Mapインタフェースのハッシュテーブルとリンクリストが実装され,予知可能な反復順序がある.この実装は、HashMapとは異なり、後者はすべてのエントリで実行される二重リンクリストを維持している.このリンクリストは、通常、キーをマッピングに挿入する順序(挿入順序)である反復順序を定義します.なお、マッピングにキーを再挿入すると、挿入順序は影響を受けません.(m.put(k,v)が呼び出される前にm.containsKey(k)がtrueを返すと、呼び出されるとキーkがマッピングmに再挿入されます.)
このインプリメンテーションは、HashMap(およびHashtable)によって提供される通常の乱雑なソート作業を回避し、TreeMapに関連するコストを増加させる必要がない.これを使用すると、元のマッピングの実装に関係なく、元の順序と同じマッピングコピーを生成できます.
void foo(Map m) {
Map copy = new LinkedHashMap(m);
...
}
この技術は、モジュールが入力によってマッピングを得て、このマッピングをコピーし、そのコピーからその順序を決定した結果を返す場合に特に有用である.(お客様が通常望んでいる内容は、その出現順序と同じです.)
========================================================
回転http://tieba.baidu.com/f?kz=602669869
LinkedHashMapの特性:Linkedの内部にprivate transient Entry headerが含まれています.に登録します.この線形構造のオブジェクトを用いると,entryが加わる前後の順序やentryがアクセスされる頻度(最もアクセスされるentryが前,最近アクセスされたentryが後)を記録するのに役立つ.大まかな過程は以下の通りである:new LinkedHashMap(10,0.75,true);前の2つのパラメータがHashMapコンストラクション関数に必要なパラメータであり、後のtrueはLinkedHashMapがアクセス順にソートされていることを示しています.LinkedHashMapのget(key)またはput(key,value)を呼び出すと、たまたまkeyがmapに含まれ、LinkedHashMapはkeyオブジェクトのentryを線形構造の最後に配置します.挿入順序に従ってソートする意味:get(key)を呼び出すか、put(key,value)は線形構造に何の影響も与えません.LinkedHashMapはアクセス順にソートする機能を提供するため、HashMapのget(key)メソッド(HashMapはソートを必要としない)とHashMapを書き換える必要がある.EntryのrecordAccess(HashMap)メソッドpublic Object get(Object key){Entry=(Entry)getEntry(key);if(e==null)return null;e.recordAccess(this);return e.value; } void recordAccess(HashMap m) { LinkedHashMap lm = (LinkedHashMap)m; if (lm.accessOrder) { lm.modCount++; remove(); addBefore(lm.header); }}addBefore(lm.header)はこのentryをheader線形テーブルの最後に置くことに注意してください.(参考LinkedHashMap.Entry extends HashMap.EntryはHashMap.Entryよりbefore,afterの2つのドメインが多く、双方向である)put(key,value)メソッドについては、LinkedHashMapは書き換える必要がなく、HashMapを使えばよい.HashMapはそのput(key,value)メソッドにe.recordAccess(this)が予め残っているからである.もう一つの方法は注目に値する:protected boolean removeEldestEntry(Map.Entry eldest){return false;}put(key,value)が呼び出されると、HashMapはmapのsizeを自動的に増加させるか否かを判断し、LinkedHashMapは拡張され、removeEldestEntryメソッドreturn false;(デフォルトの実装)、LinkedHashMapはHashMapが拡張を処理する方法と一致する.removeEldestEntryがtrueを返すと、LinkedHashMapは最もよく使われていないentry(つまりheaderリニアテーブルの一番前のもの)を自動的に削除します.LinkedHashMapのドキュメントで述べたように、LinkedHashMapはまるでLRU Cache(Least Recently Used)を実現するために書かれたものです.だからこそoscacheやehcacheではLinkedHashMapが使われています.(oscacheでLRUを使用するかどうかは設定可能)