LinkedHashMap(挿入順/アクセス順保持) — LRU 実装の簡易版
Java の LinkedHashMap は、HashMap に「順序保持機能」を追加したものです。
初心者が理解すべきポイントは「挿入順/アクセス順を保持できる」「LRU(Least Recently Used)キャッシュを簡単に作れる」ということです。ここでは例題を交えて解説します。
LinkedHashMap の特徴
- HashMap と同じくキーと値を管理(検索は平均 O(1))。
- 順序保持:
- 挿入順: 追加した順番を保持。
- アクセス順: get/put でアクセスした順番を保持。
- LRU キャッシュの簡易実装:
removeEldestEntryをオーバーライドすれば、古い要素を自動削除できる。
👉 用途: 「順序付きのマップ」「キャッシュ機構」「最近使ったデータの管理」。
基本コード例
1. 挿入順保持
import java.util.LinkedHashMap;
public class InsertOrderDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("A", "Apple");
map.put("B", "Banana");
map.put("C", "Cherry");
System.out.println(map); // {A=Apple, B=Banana, C=Cherry}
}
}
Java👉 HashMap だと順序は保証されないが、LinkedHashMap は挿入順を保持。
2. アクセス順保持
import java.util.LinkedHashMap;
import java.util.Map;
public class AccessOrderDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<>(16, 0.75f, true);
map.put("A", "Apple");
map.put("B", "Banana");
map.put("C", "Cherry");
// アクセス
map.get("A");
map.get("B");
System.out.println(map); // {C=Cherry, A=Apple, B=Banana}
}
}
Java👉 コンストラクタの第3引数 true で「アクセス順保持」に切り替え。
👉 最近アクセスした要素が末尾に移動する。
LRU キャッシュの簡易版
LinkedHashMap を継承して removeEldestEntry をオーバーライドすると、最大サイズを超えたら古い要素を自動削除できます。
例題: LRU キャッシュ
import java.util.LinkedHashMap;
import java.util.Map;
class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int maxSize;
public LRUCache(int maxSize) {
super(16, 0.75f, true); // アクセス順保持
this.maxSize = maxSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxSize; // サイズ超過で最古の要素削除
}
}
public class LRUCacheDemo {
public static void main(String[] args) {
LRUCache<Integer, String> cache = new LRUCache<>(3);
cache.put(1, "One");
cache.put(2, "Two");
cache.put(3, "Three");
cache.get(1); // 1 をアクセス → 最近使用扱い
cache.put(4, "Four"); // サイズ超過 → 最古の 2 が削除
System.out.println(cache); // {3=Three, 1=One, 4=Four}
}
}
Java👉 動き:
- 最大サイズ 3。
- 4 を追加した時点で最古の「2」が削除される。
- 最近アクセスした「1」は残る。
テンプレート集
挿入順保持
LinkedHashMap<K, V> map = new LinkedHashMap<>();
Javaアクセス順保持
LinkedHashMap<K, V> map = new LinkedHashMap<>(initialCapacity, loadFactor, true);
JavaLRU キャッシュ
class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int maxSize;
public LRUCache(int maxSize) { super(16, 0.75f, true); this.maxSize = maxSize; }
@Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxSize;
}
}
Java実務でのコツ
- キャッシュ用途: DBやAPIの結果をキャッシュして高速化。
- 順序付き出力: ログや履歴を「追加順」で保持したいときに便利。
- アクセス順での管理: 最近使ったデータを優先的に残す仕組みが簡単に作れる。
- スレッド安全:
LinkedHashMapはスレッドセーフではない。複数スレッドで使う場合はCollections.synchronizedMapやConcurrentHashMapを検討。
まとめ
- LinkedHashMap は「順序保持できる HashMap」。
- 挿入順/アクセス順を選べる。
- LRU キャッシュは
removeEldestEntryを使えば簡単に実装可能。
👉 練習課題として「最大5件まで保持する LRU キャッシュ」を作り、アクセス順に並び替えながらデータを追加してみると、LinkedHashMap の便利さが体感できます。
