Знакомство с WeakHashMap

Класс WeakHashMap — реализация хеширования, которая содержит WeakReference для своих ключей.

Как и HashMap, он также поддерживает null ключ и null значения. Мы можем создать WeakHashMap, используя один из доступных конструкторов:

    WeakHashMap (): создает пустой WeakHashMap с емкостью по умолчанию (16) и коэффициентом загрузки по умолчанию (0,75)

  • WeakHashMap (int initialCapacity): создает пустой WeakHashMap с заданной емкостью и коэффициентом загрузки по умолчанию
  • WeakHashMap (int initialCapacity, float loadFactor): использует заданную начальную емкость и коэффициент загрузки для создания экземпляра WeakHashMap
  • WeakHashMap (Map <? Extends K, extends V> map): создает новый WeakHashMap с теми же отображениями, что и указанная карта

Давай быстро создадим экземпляр WeakHashMap, используя конструктор по умолчанию:


WeakHashMap<Integer, String> map = new WeakHashMap<>();

Методы в WeakHashMap

WeakHashMap реализует интерфейс Map и поэтому наследует все его методы. Рассмотрим наиболее часто используемые методы:

  • V put (ключ K, значение V) вставляет новую пару ключ-значение в WeakHashMap. Если карта уже содержит данный ключ, его значение заменяется.
  • V get (Object key) извлекает значение данного ключа. Возвращает null, если карта не содержит сопоставления для ключа.
  • V remove (Object key) удаляет запись с данным ключом и возвращает соответствующее значение.
  • containsKey (Object key) возвращает true, если карта содержит данный ключ, иначе false.
  • boolean containsValue (Object value) проверяет, содержит ли карта заданное значение int size (): получает размер WeakHashMap.
  • boolean isEmpty () возвращает, является ли карта пустой или нет.
  • Set <Map.Entry <K, V >> entrySet () возвращает представление Set отображений, содержащихся в карте.
  • Set <K> keySet () возвращает представление Set ключей, содержащихся на карте.
  • Collection <V> values ​​() возвращает представление коллекции значений, содержащихся в карте.

Давай попробуем несколько из этих методов:


map.put(1, "A");
map.put(2, "B");
  
System.out.println(map.containsKey(1)); //true
System.out.println(map.containsKey(3)); //false
System.out.println(map.containsValue("B")); //true
  
String val = map.get(2); // "B"
int size = map.size(); //2
  
for(Map.Entry<Integer, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ":" + entry.getValue());
}

Примеры использования

WeakHashMap, в отличие от HashMap, хранит слабые ссылки на ключи.

Теперь попробуем понять эту концепцию с помощью примера.

Предположим, у нас есть класс User:


class User {
  
    private int id;
    private String name;
       
    public String toString() {
        return "[User{id=" + id + " ,name=" + name + "}]";
    }
}

И скажем, мы определяем WeakHashMap <User, Integer>, в котором хранится число зависимых для каждого User:


Map<User, Integer> weakHashMap = new WeakHashMap<>();
  
User vova = new Employee(1, "Vladimir");
User gena = new Employee(2, "Genady");
  
weakHashMap.put(vova 3);
weakHashMap.put(gena, 4);
  
System.out.println(weakHashMap);
 //{[User{id=1 ,name=Vladimir}]=3, [User{id=2 ,name=Genady}]=4}
  
gena = null;
  
System.gc();
  
System.out.println(weakHashMap); //{[User{id=1 ,name=Vladimir}]=3}

Мы видим, что наша WeakHashMap больше не содержит запись для gena. Получается, что объект, на который указывает gena, потерял свою единственную сильную ссылку в тот момент, когда мы установили для него значение null, и стал подходящим для сбора мусора. При запросе сборки мусора с помощью System.gc () сборщик мусора удалил эту запись из WeakHashMap.

Сравнение HashMap и WeakHashMap

Давай обсудим важные различия между HashMap и WeakHashMap:

HashMap WeakHashMap
Сохраненный объект записи не подходит для сборки мусора Запись в WeakHashMap будет автоматически удалена, когда ее ключ потеряет все сильные и мягкие ссылки
HashMap содержит сильные ссылки для своих ключевых объектов Слабые ссылки на ключи хранятся в случае WeakHashMap
Метод size () всегда будет возвращать одно и то же значение, если только мы явно не добавим или не удалим записи Метод size () может возвращать меньшее значение, поскольку GC может автоматически удалять несколько записей
HashMap реализует интерфейс Cloneable, и его метод clone () возвращает поверхностную копию HashMap Не реализует Cloneable
Реализует интерфейс Serializable Не поддерживает сериализацию

WeakHashMap хранит слабые ссылки на свои ключевые объекты, поэтому записи могут автоматически удаляться, когда ключ теряет все обычные ссылки.