Статьи

WeakHashMap в Java

WeakHashMap в Java — довольно популярная структура данных среди разработчиков Java среднего и старшего уровня.

Класс WeakHashMap присутствует в пакете java.util . Это реализация Map, которая хранит слабые ссылки на свои ключи. Запись в WeakHashMap автоматически удаляется, когда связанный ключ теряет все свои активные сильные и мягкие ссылки.

В этом посте мы сначала поговорим о типах ссылок в Java — Soft, Weak и Strong. И тогда мы узнаем о WeakHashMap .

Типы Java Ссылки:

Java позволяет иметь три разных типа ссылок:

1. Сильные ссылки:

Сильные ссылки — это те, которые мы используем в нашем повседневном программировании на Java:

1
Employee emp = new Employee("Jake");

Любой объект, на который ссылается строгая ссылка, не подходит для сборки мусора.

2. Мягкие ссылки:

Объект, на который указывает мягкая ссылка, не будет собирать мусор, пока JVM не будет нуждаться в памяти. Мы можем создать java.lang.ref. SoftReference, например :

1
SoftReference<Employee> empSoft = new SoftReference<>(new Employee("Jake"));

3. Слабые ссылки:

Мы можем создать WeakReference с помощью класса java.lang.ref.WeakReference . Любой объект, который теряет все сильные и мягкие ссылки, сразу же становится пригодным для сборки мусора , даже если у нас есть несколько слабых ссылок, указывающих на это:

1
2
3
4
5
6
7
Employee jake = new Employee("Jake");
Employee jakeOtherStrongRef = jake;
  
WeakReference<Employee> emp = new WeakReference<>(jake);
  
jake = null; // object not yet eligible for GC as jakeOtherStrongRef also exists
jakeOtherStrongRef = null; //object is now eligible for GC

Построение WeakHashMap :

Java WeakHashMap — это реализация хеширования, которая содержит WeakReference для своих ключей . Как и HashMap , он также поддерживает нулевой ключ и нулевые значения. Мы можем создать 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, используя конструктор по умолчанию:

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

Методы в WeakHashMap :

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

  • V put (ключ K, значение V): вставляет новую пару ключ-значение в WeakHashMap . Если карта уже содержит данный ключ, его значение заменяется
  • V get (Object key): извлекает значение данного ключа. Возвращает ноль, если карта не содержит сопоставления для ключа
  • V remove (Object key): удаляет запись с данным ключом и возвращает соответствующее значение
  • boolean 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 ​​(): возвращает представление коллекции значений, содержащихся в карте

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

01
02
03
04
05
06
07
08
09
10
11
12
13
map.put(1, "Argon");
map.put(2, "Nitrogen");
  
System.out.println(map.containsKey(1)); //true
System.out.println(map.containsKey(3)); //false
System.out.println(map.containsValue("Nitrogen")); //true
  
String val = map.get(2); // "Nitrogen"
int size = map.size(); //2
  
for(Map.Entry<Integer, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ":" + entry.getValue());
}

Как работает WeakHashMap ?

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

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

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

01
02
03
04
05
06
07
08
09
10
11
class Employee {
  
    private int id;
    private String name;
  
    //constructors, getters and setters
     
    public String toString() {
        return "[Employee{id=" + id + " ,name=" + name + "}]";
    }
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Map<Employee, Integer> weakHashMap = new WeakHashMap<>();
  
Employee ray = new Employee(1, "Ray");
Employee sierra = new Employee(2, "Sierra");
  
weakHashMap.put(ray, 3);
weakHashMap.put(sierra, 4);
  
System.out.println(weakHashMap);
 //{[Employee{id=1 ,name=Ray}]=3, [Employee{id=2 ,name=Sierra}]=4}
  
sierra = null;
  
System.gc();
  
System.out.println(weakHashMap); //{[Employee{id=1 ,name=Ray}]=3}

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

HashMap против WeakHashMap :

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

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

Вывод:

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

Оставьте первый комментарий.

Опубликовано на Java Code Geeks с разрешения Шубхры Шриваставы, партнера нашей программы JCG . Смотрите оригинальную статью здесь: WeakHashMap In Java

Мнения, высказанные участниками Java Code Geeks, являются их собственными.