Java : WeakHashMap (弱参照マップ) - API使用例
WeakHashMap (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
WeakHashMap は、弱参照 のキーを持つ Map です。
弱参照のキーが GC でクリアされると、マップから要素が自動的に削除されます。
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
var key1 = new Key("aaa");
var key2 = new Key("bbb");
map.put(key1, 100);
map.put(key2, 200);
System.out.println(map); // {bbb=200, aaa=100}
System.gc();
System.out.println(map); // {bbb=200, aaa=100}
key1 = null;
System.gc();
System.out.println(map); // {bbb=200}
key2 = null;
System.gc();
System.out.println(map); // {}
補足
- 本記事のコード例では、GCを実行するために System.gc メソッドを使っています。
- しかし、一般的なJavaプログラムでは、System.gc を直接呼び出すことはあまりおすすめしません。
Javaシステムが自分自身の最適なタイミングでGCを実行してくれるためです。
コンストラクタ
WeakHashMap ()
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
System.out.println(map); // {}
System.out.println(map.isEmpty()); // true
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.size()); // 3
WeakHashMap (int initialCapacity)
初期容量を変えて処理時間を計った例です。
(実行する環境によって変わる可能性があります)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>(10000000);
System.out.println(map); // {}
final var startTime = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
map.put(new Key(String.valueOf(i)), i);
}
final var endTime = System.nanoTime();
// 0.205931 sec.
System.out.printf("%f sec.%n", (endTime - startTime) / 1000000000.0);
final var map = new WeakHashMap<Key, Integer>(1);
System.out.println(map); // {}
final var startTime = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
map.put(new Key(String.valueOf(i)), i);
}
final var endTime = System.nanoTime();
// 0.278058 sec.
System.out.printf("%f sec.%n", (endTime - startTime) / 1000000000.0);
WeakHashMap (int initialCapacity, float loadFactor)
負荷係数を変えて処理時間を計った例です。
(実行する環境によって変わる可能性があります)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>(16, 0.05f);
System.out.println(map); // {}
final var startTime = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
map.put(new Key(String.valueOf(i)), i);
}
final var endTime = System.nanoTime();
// 0.367535 sec.
System.out.printf("%f sec.%n", (endTime - startTime) / 1000000000.0);
final var map = new WeakHashMap<Key, Integer>(16, 0.75f);
System.out.println(map); // {}
final var startTime = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
map.put(new Key(String.valueOf(i)), i);
}
final var endTime = System.nanoTime();
// 0.285230 sec.
System.out.printf("%f sec.%n", (endTime - startTime) / 1000000000.0);
WeakHashMap (Map<? extends K,? extends V> m)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var m = Map.of(new Key("a"), 10, new Key("b"), 20, new Key("c"), 30);
final var map = new WeakHashMap<>(m);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.size()); // 3
メソッド
void clear ()
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.size()); // 3
map.clear();
System.out.println(map); // {}
System.out.println(map.size()); // 0
boolean containsKey (Object key)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.containsKey(new Key("a"))); // true
System.out.println(map.containsKey(new Key("b"))); // true
System.out.println(map.containsKey(new Key("c"))); // true
System.out.println(map.containsKey(new Key("X"))); // false
System.out.println(map.containsKey(new Key(""))); // false
boolean containsValue (Object value)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
map.put(new Key("X"), 30);
System.out.println(map); // {X=30, a=10, c=30, b=20}
System.out.println(map.containsValue(0)); // false
System.out.println(map.containsValue(10)); // true
System.out.println(map.containsValue(20)); // true
System.out.println(map.containsValue(30)); // true
System.out.println(map.containsValue(40)); // false
Set<Map.Entry<K,V>> entrySet ()
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 1);
map.put(new Key("b"), 2);
map.put(new Key("c"), 3);
System.out.println(map); // {a=1, c=3, b=2}
final var entries = map.entrySet();
System.out.println(entries); // [a=1, c=3, b=2]
map.replace(new Key("b"), 20);
System.out.println(map); // {a=1, c=3, b=20}
System.out.println(entries); // [a=1, c=3, b=20]
entries.remove(Map.entry(new Key("a"), 1));
System.out.println(map); // {c=3, b=20}
System.out.println(entries); // [c=3, b=20]
for (final var entry : entries) {
entry.setValue(entry.getValue() * 10);
}
System.out.println(map); // {c=30, b=200}
System.out.println(entries); // [c=30, b=200]
V get (Object key)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.get(new Key("a"))); // 10
System.out.println(map.get(new Key("b"))); // 20
System.out.println(map.get(new Key("c"))); // 30
System.out.println(map.get(new Key("X"))); // null
System.out.println(map.get(new Key(""))); // null
boolean isEmpty ()
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.size()); // 3
System.out.println(map.isEmpty()); // false
map.clear();
System.out.println(map); // {}
System.out.println(map.size()); // 0
System.out.println(map.isEmpty()); // true
Set<K> keySet ()
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
final var keys = map.keySet();
System.out.println(keys); // [a, c, b]
map.put(new Key("d"), 40);
System.out.println(map); // {a=10, c=30, b=20, d=40}
System.out.println(keys); // [a, c, b, d]
keys.remove(new Key("a"));
System.out.println(map); // {c=30, b=20, d=40}
System.out.println(keys); // [c, b, d]
V put (K key, V value)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
System.out.println(map); // {}
System.out.println(map.put(new Key("a"), 1)); // null
System.out.println(map); // {a=1}
System.out.println(map.put(new Key("b"), 2)); // null
System.out.println(map); // {a=1, b=2}
System.out.println(map.put(new Key("c"), 3)); // null
System.out.println(map); // {a=1, c=3, b=2}
System.out.println(map.put(new Key("a"), 999)); // 1
System.out.println(map); // {a=999, c=3, b=2}
void putAll (Map<? extends K,? extends V> m)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
System.out.println(map); // {}
map.putAll(Map.of());
System.out.println(map); // {}
map.putAll(Map.of(new Key("a"), 1, new Key("b"), 2));
System.out.println(map); // {a=1, b=2}
map.putAll(Map.of(new Key("c"), 3, new Key("d"), 4, new Key("e"), 5));
System.out.println(map); // {a=1, c=3, b=2, e=5, d=4}
map.putAll(Map.of(new Key("a"), 901, new Key("b"), 902, new Key("z"), 100));
System.out.println(map); // {z=100, a=901, c=3, b=902, e=5, d=4}
V remove (Object key)
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 10);
map.put(new Key("b"), 20);
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.remove(new Key("b"))); // 20
System.out.println(map); // {a=10, c=30}
System.out.println(map.remove(new Key("z"))); // null
System.out.println(map); // {a=10, c=30}
int size ()
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
System.out.println(map); // {}
System.out.println(map.size()); // 0
map.put(new Key("a"), 10);
System.out.println(map); // {a=10}
System.out.println(map.size()); // 1
map.put(new Key("b"), 20);
System.out.println(map); // {a=10, b=20}
System.out.println(map.size()); // 2
map.put(new Key("c"), 30);
System.out.println(map); // {a=10, c=30, b=20}
System.out.println(map.size()); // 3
Collection<V> values ()
record Key(String s) {
@Override
public String toString() {
return s;
}
}
final var map = new WeakHashMap<Key, Integer>();
map.put(new Key("a"), 1);
map.put(new Key("b"), 2);
map.put(new Key("c"), 3);
System.out.println(map); // {a=1, c=3, b=2}
final var values = map.values();
System.out.println(values); // [1, 3, 2]
map.replace(new Key("b"), 20);
System.out.println(map); // {a=1, c=3, b=20}
System.out.println(values); // [1, 3, 20]
values.remove(1);
System.out.println(map); // {c=3, b=20}
System.out.println(values); // [3, 20]
//values.add(4); // UnsupportedOperationException
AbstractMapで宣言されたメソッド
clone, equals, hashCode, toString
「Java API 使用例 : AbstractMap」をご参照ください。
Mapで宣言されたメソッド
compute, computeIfAbsent, computeIfPresent, equals, forEach, getOrDefault, hashCode, merge, putIfAbsent, remove, replace, replace, replaceAll
「Java API 使用例 : Map」をご参照ください。