Java WeakHashMap: понимание, использование и ключевые отличия
Java WeakHashMap
Подробное руководство по Java WeakHashMap, охватывающее его создание, ключевые отличия от HashMap, практические примеры и основные методы.
Класс WeakHashMap является частью Java Collections Framework и реализует интерфейс Map. Он ведёт себя как обычная хеш-таблица, но хранит ключи как слабые ссылки, позволяя им быть собранными сборщиком мусора, когда они больше не используются.
Примечание: Ключи в WeakHashMap обёрнуты в объекты WeakReference.
Слабая ссылка может быть собрана сборщиком мусора, если программа больше не держит сильную ссылку на объект-ключ.
Создание WeakHashMap
Сначала импортируйте java.util.WeakHashMap:
import java.util.WeakHashMap;
Затем создайте экземпляр, опционально указывая начальную ёмкость и коэффициент загрузки:
// WeakHashMap с ёмкостью 8 и коэффициентом загрузки 0.6
WeakHashMap<Key, Value> numbers = new WeakHashMap<>(8, 0.6);
Параметры:
- capacity — количество записей, которые карта может содержать до ресайза. По умолчанию 16.
- loadFactor — порог расширения карты. По умолчанию 0.75.
Когда параметры не указаны, применяются значения по умолчанию:
WeakHashMap<Key, Value> numbers = new WeakHashMap<>();
HashMap против WeakHashMap
Хотя оба реализуют Map, ключевое различие в силе ссылок:
- HashMap — ключи являются сильными ссылками; записи существуют до явного удаления.
- WeakHashMap — ключи являются слабыми ссылками; записи исчезают, когда ключ больше не достижим.
Пример, демонстрирующее поведение:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
String two = new String("Two");
Integer twoValue = 2;
String four = new String("Four");
Integer fourValue = 4;
numbers.put(two, twoValue);
numbers.put(four, fourValue);
System.out.println("WeakHashMap: " + numbers);
// Обнуляем ссылку на ключ two
two = null;
System.gc();
System.out.println("WeakHashMap after GC: " + numbers);
}
}
Вывод:
WeakHashMap: {Four=4, Two=2} WeakHashMap after GC: {Four=4}
Запись для "Two" исчезает, потому что её ключ больше не сильно достижим. В отличие от этого, HashMap удерживал бы запись:
import java.util.HashMap;
class Main {
public static void main(String[] args) {
HashMap<String, Integer> numbers = new HashMap<>();
String two = new String("Two");
Integer twoValue = 2;
String four = new String("Four");
Integer fourValue = 4;
numbers.put(two, twoValue);
numbers.put(four, fourValue);
System.out.println("HashMap: " + numbers);
two = null;
System.gc();
System.out.println("HashMap after GC: " + numbers);
}
}
Вывод:
HashMap: {Four=4, Two=2} HashMap after GC: {Four=4, Two=2}
Таким образом, WeakHashMap идеален, когда нужно, чтобы карта автоматически освобождала память, связанную с неиспользуемыми ключами.
Преобразование из другой карты
Создайте WeakHashMap из существующей карты для копирования её записей:
import java.util.HashMap;
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
HashMap<String, Integer> evenNumbers = new HashMap<>();
String two = new String("Two");
evenNumbers.put(two, 2);
System.out.println("HashMap: " + evenNumbers);
WeakHashMap<String, Integer> numbers = new WeakHashMap<>(evenNumbers);
System.out.println("WeakHashMap: " + numbers);
}
}
Вывод:
HashMap: {Two=2} WeakHashMap: {Two=2}
Ключевые методы WeakHashMap
Ниже приведен выбор наиболее часто используемых операций.
Вставка записей
put(key, value)— добавляет отображение.putAll(map)— объединяет другую карту.putIfAbsent(key, value)— вставляет только если ключ отсутствует.
Пример:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> evenNumbers = new WeakHashMap<>();
evenNumbers.put(new String("Two"), 2);
evenNumbers.putIfAbsent(new String("Four"), 4);
System.out.println("Even numbers: " + evenNumbers);
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
numbers.put(new String("One"), 1);
numbers.putAll(evenNumbers);
System.out.println("All numbers: " + numbers);
}
}
Вывод:
Even numbers: {Four=4, Two=2} All numbers: {Two=2, Four=4, One=1}
Доступ к записям
Получите данные через:
get(key)— возвращает значение илиnull, если отсутствует.getOrDefault(key, default)— возвращает значение по умолчанию, когда ключ отсутствует.entrySet(),keySet(),values()— итерация по записям, ключам или значениям.
Пример:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
numbers.put(new String("One"), 1);
numbers.put(new String("Two"), 2);
System.out.println("Map: " + numbers);
System.out.println("Entry set: " + numbers.entrySet());
System.out.println("Keys: " + numbers.keySet());
System.out.println("Values: " + numbers.values());
System.out.println("Get Two: " + numbers.get("Two"));
System.out.println("GetOrDefault Four: " + numbers.getOrDefault("Four", 4));
}
}
Вывод:
Map: {Two=2, One=1} Entry set: [Two=2, One=1] Keys: [Two, One] Values: [1, 2] Get Two: 2 GetOrDefault Four: 4
Удаление записей
remove(key)— удаляет и возвращает значение.remove(key, value)— удаляет только если текущее отображение совпадает с предоставленным значением.clear()— очищает карту.containsKey(key),containsValue(value),size(),isEmpty()
Пример:
import java.util.WeakHashMap;
class Main {
public static void main(String[] args) {
WeakHashMap<String, Integer> numbers = new WeakHashMap<>();
numbers.put(new String("One"), 1);
numbers.put(new String("Two"), 2);
System.out.println("Map: " + numbers);
int removed = numbers.remove("Two");
System.out.println("Removed value: " + removed);
boolean removedIf = numbers.remove("One", 3);
System.out.println("Removed {One=3}? " + removedIf);
System.out.println("After removal: " + numbers);
}
}
Вывод:
Map: {Two=2, One=1} Removed value: 2 Removed {One=3}? false After removal: {One=1}
Дополнительные утилиты
| Метод | Описание |
|---|---|
clear() | Удаляет все записи. |
containsKey(key) | Проверяет существование ключа. |
containsValue(value) | Проверяет наличие значения. |
size() | Возвращает количество записей. |
isEmpty() | Возвращает true, если карта не имеет записей. |
Для более глубокого погружения обратитесь к официальной документации Java WeakHashMap.
java
- Освоение операторов Java: типы, синтаксис и практические примеры
- Комментарии в Java: типы, использование и лучшие практики
- Освоение улучшенного цикла for в Java: синтаксис, примеры и лучшие практики
- Освоение строк в Java: создание, методы и лучшие практики
- Интерфейсы в Java: концепции, реализация и лучшие практики
- Анонимные внутренние классы в Java: определение, синтаксис и практические примеры
- Try-with-resources в Java: автоматическое управление ресурсами
- Аннотации в Java: типы, размещение и практические примеры
- Assertions в Java: практическое руководство по обнаружению багов и обеспечению надежности кода
- Понимание Java Vector: использование, особенности и сравнение с ArrayList