Внутреннее устройство LinkedHashMap
1. Связанный список для порядка элементов
LinkedHashMap расширяет HashMap, добавляя поддержку связанного списка для поддержания порядка элементов. Каждый элемент хранится в виде узла двусвязного списка, что позволяет поддерживать порядок вставки или порядок доступа.
2. Поля для управления порядком
LinkedHashMap добавляет два новых поля для управления порядком элементов:
Эти поля указывают на первый и последний элементы в связанном списке.
3. Механизм управления порядком элементов
Для управления порядком элементов LinkedHashMap переопределяет методы newNode, afterNodeAccess и afterNodeInsertion:
newNode: Создает новый узел и добавляет его в конец связанного списка.
afterNodeAccess: Обновляет порядок элементов при доступе, если карта настроена на порядок доступа.
afterNodeInsertion: Удаляет самый старый элемент, если карта настроена на удаление старейших элементов.
Основные методы LinkedHashMap
1. Конструкторы
LinkedHashMap предоставляет несколько конструкторов для создания карты с различными настройками:
2. Метод put
Метод put добавляет пару ключ-значение в карту. Если ключ уже существует, его значение обновляется.
3. Метод get
Метод get возвращает значение, связанное с указанным ключом. Если ключ не найден, возвращается null. При этом порядок элементов обновляется, если карта настроена на порядок доступа.
4. Метод remove
Метод remove удаляет пару ключ-значение по указанному ключу и возвращает удаленное значение.
5. Метод containsKey
Метод containsKey проверяет, содержит ли карта указанный ключ.
#Java #Training #Medium #LinkedHashMap
1. Связанный список для порядка элементов
LinkedHashMap расширяет HashMap, добавляя поддержку связанного списка для поддержания порядка элементов. Каждый элемент хранится в виде узла двусвязного списка, что позволяет поддерживать порядок вставки или порядок доступа.
static class Entry<K, V> extends HashMap.Node<K, V> {
Entry<K, V> before, after;
Entry(int hash, K key, V value, HashMap.Node<K, V> next) {
super(hash, key, value, next);
}
}
2. Поля для управления порядком
LinkedHashMap добавляет два новых поля для управления порядком элементов:
transient LinkedHashMap.Entry<K, V> head;
transient LinkedHashMap.Entry<K, V> tail;
Эти поля указывают на первый и последний элементы в связанном списке.
3. Механизм управления порядком элементов
Для управления порядком элементов LinkedHashMap переопределяет методы newNode, afterNodeAccess и afterNodeInsertion:
newNode: Создает новый узел и добавляет его в конец связанного списка.
Node<K, V> newNode(int hash, K key, V value, Node<K, V> e) {
LinkedHashMap.Entry<K, V> p = new LinkedHashMap.Entry<>(hash, key, value, e);
linkNodeLast(p);
return p;
}
private void linkNodeLast(LinkedHashMap.Entry<K, V> p) {
LinkedHashMap.Entry<K, V> last = tail;
tail = p;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
}
afterNodeAccess: Обновляет порядок элементов при доступе, если карта настроена на порядок доступа.
void afterNodeAccess(Node<K, V> e) {
LinkedHashMap.Entry<K, V> last;
if (accessOrder && (last = tail) != e) {
LinkedHashMap.Entry<K, V> p = (LinkedHashMap.Entry<K, V>) e, b = p.before, a = p.after;
p.after = null;
if (b == null)
head = a;
else
b.after = a;
if (a != null)
a.before = b;
else
last = b;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}
afterNodeInsertion: Удаляет самый старый элемент, если карта настроена на удаление старейших элементов.
void afterNodeInsertion(boolean evict) {
LinkedHashMap.Entry<K, V> first;
if (evict && (first = head) != null && removeEldestEntry(first)) {
K key = first.key;
removeNode(hash(key), key, null, false, true);
}
}
Основные методы LinkedHashMap
1. Конструкторы
LinkedHashMap предоставляет несколько конструкторов для создания карты с различными настройками:
public LinkedHashMap() {
super();
}
public LinkedHashMap(int initialCapacity) {
super(initialCapacity);
}
public LinkedHashMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
}
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
2. Метод put
Метод put добавляет пару ключ-значение в карту. Если ключ уже существует, его значение обновляется.
public V put(K key, V value) {
return super.put(key, value);
}
3. Метод get
Метод get возвращает значение, связанное с указанным ключом. Если ключ не найден, возвращается null. При этом порядок элементов обновляется, если карта настроена на порядок доступа.
public V get(Object key) {
Node<K, V> e;
if ((e = getNode(hash(key), key)) == null)
return null;
if (accessOrder)
afterNodeAccess(e);
return e.value;
}
4. Метод remove
Метод remove удаляет пару ключ-значение по указанному ключу и возвращает удаленное значение.
public V remove(Object key) {
Node<K, V> e;
return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value;
}
5. Метод containsKey
Метод containsKey проверяет, содержит ли карта указанный ключ.
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
#Java #Training #Medium #LinkedHashMap
6. Метод containsValue
Метод containsValue проверяет, содержит ли карта указанное значение.
7. Метод clear
Метод clear очищает карту, удаляя все элементы.
8. Метод entrySet
Метод entrySet возвращает набор всех пар ключ-значение в карте.
#Java #Training #Medium #LinkedHashMap
Метод containsValue проверяет, содержит ли карта указанное значение.
public boolean containsValue(Object value) {
for (Node<K, V> e = head; e != null; e = e.after) {
if (value.equals(e.value))
return true;
}
return false;
}
7. Метод clear
Метод clear очищает карту, удаляя все элементы.
public void clear() {
super.clear();
head = tail = null;
}
8. Метод entrySet
Метод entrySet возвращает набор всех пар ключ-значение в карте.
public Set<Map.Entry<K, V>> entrySet() {
return new LinkedEntrySet();
}
#Java #Training #Medium #LinkedHashMap
Введение в TreeMap, принципы работы и внутреннее устройство
TreeMap — это реализация интерфейса NavigableMap, основанная на красно-черном дереве. Он предоставляет отсортированное отображение ключей и является мощным инструментом для хранения отсортированных данных.
Основные особенности TreeMap
Отсортированное отображение: Ключи в TreeMap всегда отсортированы в порядке возрастания, если не указан другой компаратор.
Красно-черное дерево: Использует самобалансирующееся бинарное дерево для хранения элементов.
Эффективность: Операции вставки, удаления и поиска выполняются за O(log n).
Внутреннее устройство TreeMap
Красно-черное дерево — это тип самобалансирующегося бинарного дерева поиска с следующими свойствами:
Каждый узел либо красный, либо черный.
Корень дерева всегда черный.
Все листья (NULL-указатели) считаются черными.
Красный узел не может иметь красных дочерних узлов (т.е., красные узлы не могут быть рядом).
Любой путь от корня до листа содержит одинаковое количество черных узлов.
Класс Entry
Внутренний класс Entry представляет узел в дереве:
Принципы работы TreeMap
Вставка
При вставке элемента TreeMap сначала находит подходящее место для нового элемента, а затем вставляет его как красный узел и балансирует дерево.
Удаление
Удаление элемента включает три основных шага:
Найти узел для удаления.
Удалить узел.
Балансировать дерево, если это необходимо.
Поиск
Поиск элемента осуществляется путем последовательного сравнения ключей и движения по дереву (влево или вправо), пока не будет найден нужный ключ.
Основные методы TreeMap
Метод put
Метод put добавляет пару ключ-значение в TreeMap:
Метод get
Метод get возвращает значение по ключу:
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://javarush.com/groups/posts/2584-osobennosti-treemap
https://www.baeldung.com/java-treemap
#Java #Training #Medium #TreeMap
TreeMap — это реализация интерфейса NavigableMap, основанная на красно-черном дереве. Он предоставляет отсортированное отображение ключей и является мощным инструментом для хранения отсортированных данных.
Основные особенности TreeMap
Отсортированное отображение: Ключи в TreeMap всегда отсортированы в порядке возрастания, если не указан другой компаратор.
Красно-черное дерево: Использует самобалансирующееся бинарное дерево для хранения элементов.
Эффективность: Операции вставки, удаления и поиска выполняются за O(log n).
Внутреннее устройство TreeMap
Красно-черное дерево — это тип самобалансирующегося бинарного дерева поиска с следующими свойствами:
Каждый узел либо красный, либо черный.
Корень дерева всегда черный.
Все листья (NULL-указатели) считаются черными.
Красный узел не может иметь красных дочерних узлов (т.е., красные узлы не могут быть рядом).
Любой путь от корня до листа содержит одинаковое количество черных узлов.
Класс Entry
Внутренний класс Entry представляет узел в дереве:
static final class Entry<K, V> implements Map.Entry<K, V> {
K key;
V value;
Entry<K, V> left, right, parent;
boolean color = BLACK;
Entry(K key, V value, Entry<K, V> parent) {
this.key = key;
this.value = value;
this.parent = parent;
}
public K getKey() { return key; }
public V getValue() { return value; }
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
}
Принципы работы TreeMap
Вставка
При вставке элемента TreeMap сначала находит подходящее место для нового элемента, а затем вставляет его как красный узел и балансирует дерево.
Удаление
Удаление элемента включает три основных шага:
Найти узел для удаления.
Удалить узел.
Балансировать дерево, если это необходимо.
Поиск
Поиск элемента осуществляется путем последовательного сравнения ключей и движения по дереву (влево или вправо), пока не будет найден нужный ключ.
Основные методы TreeMap
Метод put
Метод put добавляет пару ключ-значение в TreeMap:
public V put(K key, V value) {
Entry<K, V> t = root;
if (t == null) {
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K, V> parent;
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0) t = t.left;
else if (cmp > 0) t = t.right;
else return t.setValue(value);
} while (t != null);
} else {
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0) t = t.left;
else if (cmp > 0) t = t.right;
else return t.setValue(value);
} while (t != null);
}
Entry<K, V> e = new Entry<>(key, value, parent);
if (cmp < 0) parent.left = e;
else parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
Метод get
Метод get возвращает значение по ключу:
public V get(Object key) {
Entry<K, V> p = getEntry(key);
return (p == null ? null : p.value);
}
final Entry<K, V> getEntry(Object key) {
if (comparator != null) return getEntryUsingComparator(key);
Comparable<? super K> k = (Comparable<? super K>) key;
Entry<K, V> p = root;
while (p != null) {
int cmp = k.compareTo(p.key);
if (cmp < 0) p = p.left;
else if (cmp > 0) p = p.right;
else return p;
}
return null;
}
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://javarush.com/groups/posts/2584-osobennosti-treemap
https://www.baeldung.com/java-treemap
#Java #Training #Medium #TreeMap
Baeldung
A Guide to TreeMap in Java | Baeldung
A quick and practical guide to TreeMap in Java.
Что выведет код?
#Tasks
public class ComplexVariableAssignmentChallenge {
public static void main(String[] args) {
int intVar1 = 8;
int intVar2 = 3;
double doubleVar1 = 4.5;
double doubleVar2 = 2.5;
String strVar1 = "Sum: ";
String strVar2 = "Product: ";
String resultSum = strVar1 + (intVar1 + doubleVar1) + ", " + (intVar2 + doubleVar2);
String resultProduct = strVar2 + (intVar1 * doubleVar1) + ", " + (intVar2 * doubleVar2);
System.out.println(resultSum);
System.out.println(resultProduct);
}
}
#Tasks
Основные методы TreeMap и их применение
Конструкторы TreeMap
Без параметров
С компаратором
Из другого Map
Из SortedMap
Основные методы TreeMap
Метод put
Добавляет пару ключ-значение. Если ключ уже существует, то значение обновляется.
Метод get
Возвращает значение, связанное с указанным ключом.
Метод remove
Удаляет запись по ключу и возвращает удаленное значение.
Метод containsKey
Проверяет, содержится ли ключ в карте.
Метод containsValue
Проверяет, содержится ли значение в карте.
Метод size
Возвращает количество элементов в карте.
Метод isEmpty
Проверяет, пуста ли карта.
Метод clear
Очищает карту, удаляя все элементы.
Специфические методы TreeMap
Метод firstKey
Возвращает первый (минимальный) ключ.
Метод lastKey
Возвращает последний (максимальный) ключ.
Метод pollFirstEntry
Удаляет и возвращает первый (минимальный) элемент.
Метод pollLastEntry
Удаляет и возвращает последний (максимальный) элемент.
Примеры использования TreeMap
Пример 1: Печать элементов в порядке возрастания ключей
Пример 2: Использование метода subMap
Возвращает отображение части карты.
Пример 3: Получение диапазона ключей
#Java #Training #Medium #TreeMap
Конструкторы TreeMap
Без параметров
TreeMap<String, Integer> map = new TreeMap<>();
С компаратором
TreeMap<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());
Из другого Map
Map<String, Integer> anotherMap = new HashMap<>();
TreeMap<String, Integer> map = new TreeMap<>(anotherMap);
Из SortedMap
SortedMap<String, Integer> sortedMap = new TreeMap<>(anotherMap);
TreeMap<String, Integer> map = new TreeMap<>(sortedMap);
Основные методы TreeMap
Метод put
Добавляет пару ключ-значение. Если ключ уже существует, то значение обновляется.
TreeMap<String, Integer> map = new TreeMap<>();
map.put("Apple", 50);
map.put("Banana", 30);
map.put("Orange", 20);
Метод get
Возвращает значение, связанное с указанным ключом.
Integer value = map.get("Apple");
System.out.println("Value for key 'Apple': " + value);
Метод remove
Удаляет запись по ключу и возвращает удаленное значение.
Integer removedValue = map.remove("Banana");
System.out.println("Removed value: " + removedValue);
Метод containsKey
Проверяет, содержится ли ключ в карте.
boolean contains = map.containsKey("Orange");
System.out.println("Contains key 'Orange': " + contains);
Метод containsValue
Проверяет, содержится ли значение в карте.
boolean containsValue = map.containsValue(20);
System.out.println("Contains value 20: " + containsValue);
Метод size
Возвращает количество элементов в карте.
int size = map.size();
System.out.println("Size of the map: " + size);
Метод isEmpty
Проверяет, пуста ли карта.
boolean isEmpty = map.isEmpty();
System.out.println("Is the map empty: " + isEmpty);
Метод clear
Очищает карту, удаляя все элементы.
map.clear();
System.out.println("Size after clear: " + map.size());
Специфические методы TreeMap
Метод firstKey
Возвращает первый (минимальный) ключ.
String firstKey = map.firstKey();
System.out.println("First key: " + firstKey);
Метод lastKey
Возвращает последний (максимальный) ключ.
String lastKey = map.lastKey();
System.out.println("Last key: " + lastKey);
Метод pollFirstEntry
Удаляет и возвращает первый (минимальный) элемент.
Map.Entry<String, Integer> firstEntry = map.pollFirstEntry();
System.out.println("Polled first entry: " + firstEntry);
Метод pollLastEntry
Удаляет и возвращает последний (максимальный) элемент.
Map.Entry<String, Integer> lastEntry = map.pollLastEntry();
System.out.println("Polled last entry: " + lastEntry);
Примеры использования TreeMap
Пример 1: Печать элементов в порядке возрастания ключей
TreeMap<String, Integer> map = new TreeMap<>();
map.put("Apple", 50);
map.put("Banana", 30);
map.put("Orange", 20);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
Пример 2: Использование метода subMap
Возвращает отображение части карты.
map.put("Grapes", 40);
SortedMap<String, Integer> subMap = map.subMap("Apple", "Orange");
for (Map.Entry<String, Integer> entry : subMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
Пример 3: Получение диапазона ключей
NavigableMap<String, Integer> tailMap = map.tailMap("Banana", true);
for (Map.Entry<String, Integer> entry : tailMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
#Java #Training #Medium #TreeMap
WeakHashMap, особенности использования
WeakHashMap — это реализация интерфейса Map, которая использует слабые ссылки на ключи. Эта структура данных особенно полезна для кеширования, где не требуется жесткая ссылка на ключи, и объекты могут быть автоматически удалены сборщиком мусора, когда они больше не используются. Рассмотрим подробно особенности и использование WeakHashMap.
Основные особенности WeakHashMap
Слабые ссылки: Ключи в WeakHashMap хранятся как слабые ссылки. Это значит, что если на объект-ключ нет жестких ссылок из других объектов, то он может быть удален сборщиком мусора.
Автоматическое удаление: При удалении ключа сборщиком мусора, соответствующая пара ключ-значение также удаляется из карты.
Потокобезопасность: WeakHashMap не является потокобезопасной и требует внешней синхронизации при доступе из нескольких потоков.
Внутреннее устройство WeakHashMap
WeakHashMap основан на массиве сегментов (bucket), где каждая ячейка массива может содержать связанный список элементов, как в HashMap. Однако, ключи хранятся в виде слабых ссылок (WeakReference), что позволяет сборщику мусора удалять их при необходимости.
Примеры использования WeakHashMap
Создание и добавление элементов
Основные методы WeakHashMap
Метод put
Добавляет пару ключ-значение в карту.
Метод get
Возвращает значение, связанное с указанным ключом.
Метод remove
Удаляет запись по ключу и возвращает удаленное значение.
Метод containsKey
Проверяет, содержится ли ключ в карте.
Метод containsValue
Проверяет, содержится ли значение в карте.
Метод size
Возвращает количество элементов в карте.
Метод isEmpty
Проверяет, пуста ли карта.
Метод clear
Очищает карту, удаляя все элементы.
Особенности использования WeakHashMap
Кеширование
WeakHashMap идеально подходит для кеширования данных, которые можно восстанавливать, если они удалены сборщиком мусора. Например, кеширование изображений в приложении, где изображения могут быть загружены повторно, если они были удалены.
Автоматическое удаление
В ситуациях, когда необходимо автоматически удалять элементы карты при отсутствии ссылок на ключи, WeakHashMap будет полезен. Например, для ассоциации метаданных с объектами без предотвращения их сборки мусора.
Полезные ссылки для более полного ознакомления с WeakHashMap (спасибо авторам за их кропотливую работу):
https://www.baeldung.com/java-weakhashmap
https://javarush.com/quests/lectures/questservlets.level18.lecture08
#Java #Training #Medium #WeakHashMap
WeakHashMap — это реализация интерфейса Map, которая использует слабые ссылки на ключи. Эта структура данных особенно полезна для кеширования, где не требуется жесткая ссылка на ключи, и объекты могут быть автоматически удалены сборщиком мусора, когда они больше не используются. Рассмотрим подробно особенности и использование WeakHashMap.
Основные особенности WeakHashMap
Слабые ссылки: Ключи в WeakHashMap хранятся как слабые ссылки. Это значит, что если на объект-ключ нет жестких ссылок из других объектов, то он может быть удален сборщиком мусора.
Автоматическое удаление: При удалении ключа сборщиком мусора, соответствующая пара ключ-значение также удаляется из карты.
Потокобезопасность: WeakHashMap не является потокобезопасной и требует внешней синхронизации при доступе из нескольких потоков.
Внутреннее устройство WeakHashMap
WeakHashMap основан на массиве сегментов (bucket), где каждая ячейка массива может содержать связанный список элементов, как в HashMap. Однако, ключи хранятся в виде слабых ссылок (WeakReference), что позволяет сборщику мусора удалять их при необходимости.
Примеры использования WeakHashMap
Создание и добавление элементов
import java.util.WeakHashMap;
import java.util.Map;
public class WeakHashMapExample {
public static void main(String[] args) {
WeakHashMap<String, String> weakMap = new WeakHashMap<>();
String key1 = new String("key1");
String key2 = new String("key2");
weakMap.put(key1, "value1");
weakMap.put(key2, "value2");
System.out.println("Before GC: " + weakMap);
key1 = null;
System.gc();
// Подождем немного, чтобы GC мог удалить key1
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("After GC: " + weakMap);
}
}
Основные методы WeakHashMap
Метод put
Добавляет пару ключ-значение в карту.
WeakHashMap<String, Integer> map = new WeakHashMap<>();
map.put("Apple", 50);
map.put("Banana", 30);
Метод get
Возвращает значение, связанное с указанным ключом.
Integer value = map.get("Apple");
System.out.println("Value for key 'Apple': " + value);
Метод remove
Удаляет запись по ключу и возвращает удаленное значение.
Integer removedValue = map.remove("Banana");
System.out.println("Removed value: " + removedValue);
Метод containsKey
Проверяет, содержится ли ключ в карте.
boolean contains = map.containsKey("Apple");
System.out.println("Contains key 'Apple': " + contains);
Метод containsValue
Проверяет, содержится ли значение в карте.
boolean containsValue = map.containsValue(50);
System.out.println("Contains value 50: " + containsValue);
Метод size
Возвращает количество элементов в карте.
int size = map.size();
System.out.println("Size of the map: " + size);
Метод isEmpty
Проверяет, пуста ли карта.
boolean isEmpty = map.isEmpty();
System.out.println("Is the map empty: " + isEmpty);
Метод clear
Очищает карту, удаляя все элементы.
map.clear();
System.out.println("Size after clear: " + map.size());
Особенности использования WeakHashMap
Кеширование
WeakHashMap идеально подходит для кеширования данных, которые можно восстанавливать, если они удалены сборщиком мусора. Например, кеширование изображений в приложении, где изображения могут быть загружены повторно, если они были удалены.
Автоматическое удаление
В ситуациях, когда необходимо автоматически удалять элементы карты при отсутствии ссылок на ключи, WeakHashMap будет полезен. Например, для ассоциации метаданных с объектами без предотвращения их сборки мусора.
Полезные ссылки для более полного ознакомления с WeakHashMap (спасибо авторам за их кропотливую работу):
https://www.baeldung.com/java-weakhashmap
https://javarush.com/quests/lectures/questservlets.level18.lecture08
#Java #Training #Medium #WeakHashMap
JavaRush
Курс All lectures for ru purposes - Лекция: Работа с WeakHashMap
Знакомство с WeakHashMap. Методы в WeakHashMap. Примеры использования. Сравнение HashMap и WeakHashMap.
Что выведет код?
#Tasks
import java.util.*;
public class AlgorithmChallenge {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(5, 2, 8, 7, 1);
Collections.sort(numbers, (a, b) -> b - a);
int sum = 0;
for (int i = 0; i < numbers.size(); i++) {
if (i % 2 == 0) {
sum += numbers.get(i) * 2;
} else {
sum -= numbers.get(i) * 3;
}
}
System.out.println("Result: " + sum);
}
}
#Tasks
Внутреннее устройство WeakHashMap
Основные компоненты
Бакеты:
WeakHashMap использует массив бакетов для хранения элементов. Каждый бакет представляет собой связанный список, который хранит элементы с одинаковым значением хэш-кода (коллизии).
Слабые ссылки (Weak References):
Ключи в WeakHashMap хранятся в виде слабых ссылок (java.lang.ref.WeakReference). Это означает, что ключи могут быть удалены сборщиком мусора, если на них больше нет жестких ссылок.
Структура записи (Entry):
Каждый элемент в WeakHashMap представлен экземпляром внутреннего класса WeakHashMap.Entry. Этот класс расширяет WeakReference<K> и содержит дополнительные поля для значения (V) и ссылки на следующий элемент в связанном списке (для коллизий).
Сборка мусора:
Сборщик мусора удаляет записи, ключи которых больше не используются. После удаления элемента его запись в бакете становится недействительной и удаляется при следующем доступе или изменении карты.
Механизм работы
Хэширование:
При добавлении элемента в карту ключ хэшируется, и результат используется для определения бакета, в который будет помещен элемент.
Добавление элементов:
Новый элемент добавляется в соответствующий бакет. Если бакет уже содержит элементы с одинаковым хэш-кодом, новый элемент добавляется в конец связанного списка.
Удаление элементов:
Когда ключ становится недоступным для приложения (не имеет жестких ссылок), сборщик мусора удаляет его запись из памяти. WeakHashMap автоматически удаляет такие записи при следующем доступе или модификации.
Примеры использования
Пример 1: Простой пример использования WeakHashMap
В этом примере мы создаем WeakHashMap и добавляем в нее две пары ключ-значение. Затем убираем жесткие ссылки на ключи и вызываем сборщик мусора. После сборки мусора элементы с ключами, на которые больше нет жестких ссылок, удаляются из карты.
Пример 2: Использование WeakHashMap для кеширования
WeakHashMap часто используется для кеширования данных, которые могут быть автоматически удалены, когда они больше не нужны. Это позволяет эффективно управлять памятью.
#Java #Training #Medium #WeakHashMap
Основные компоненты
Бакеты:
WeakHashMap использует массив бакетов для хранения элементов. Каждый бакет представляет собой связанный список, который хранит элементы с одинаковым значением хэш-кода (коллизии).
Слабые ссылки (Weak References):
Ключи в WeakHashMap хранятся в виде слабых ссылок (java.lang.ref.WeakReference). Это означает, что ключи могут быть удалены сборщиком мусора, если на них больше нет жестких ссылок.
Структура записи (Entry):
Каждый элемент в WeakHashMap представлен экземпляром внутреннего класса WeakHashMap.Entry. Этот класс расширяет WeakReference<K> и содержит дополнительные поля для значения (V) и ссылки на следующий элемент в связанном списке (для коллизий).
Сборка мусора:
Сборщик мусора удаляет записи, ключи которых больше не используются. После удаления элемента его запись в бакете становится недействительной и удаляется при следующем доступе или изменении карты.
Механизм работы
Хэширование:
При добавлении элемента в карту ключ хэшируется, и результат используется для определения бакета, в который будет помещен элемент.
Добавление элементов:
Новый элемент добавляется в соответствующий бакет. Если бакет уже содержит элементы с одинаковым хэш-кодом, новый элемент добавляется в конец связанного списка.
Удаление элементов:
Когда ключ становится недоступным для приложения (не имеет жестких ссылок), сборщик мусора удаляет его запись из памяти. WeakHashMap автоматически удаляет такие записи при следующем доступе или модификации.
Примеры использования
Пример 1: Простой пример использования WeakHashMap
import java.util.WeakHashMap;
public class WeakHashMapExample {
public static void main(String[] args) {
WeakHashMap<String, String> map = new WeakHashMap<>();
String key1 = new String("key1");
String value1 = "value1";
map.put(key1, value1);
String key2 = new String("key2");
String value2 = "value2";
map.put(key2, value2);
System.out.println("Map before GC: " + map);
// Убираем жесткие ссылки на ключи
key1 = null;
key2 = null;
// Вызываем сборщик мусора
System.gc();
// Небольшая задержка для того, чтобы сборщик мусора успел сработать
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Map after GC: " + map);
}
}
В этом примере мы создаем WeakHashMap и добавляем в нее две пары ключ-значение. Затем убираем жесткие ссылки на ключи и вызываем сборщик мусора. После сборки мусора элементы с ключами, на которые больше нет жестких ссылок, удаляются из карты.
Пример 2: Использование WeakHashMap для кеширования
WeakHashMap часто используется для кеширования данных, которые могут быть автоматически удалены, когда они больше не нужны. Это позволяет эффективно управлять памятью.
import java.util.WeakHashMap;
public class ImageCache {
private WeakHashMap<String, byte[]> cache = new WeakHashMap<>();
public byte[] getImage(String imageName) {
byte[] image = cache.get(imageName);
if (image == null) {
image = loadImageFromDisk(imageName);
cache.put(imageName, image);
}
return image;
}
private byte[] loadImageFromDisk(String imageName) {
// Заглушка для примера, возвращаем пустой массив
return new byte[0];
}
public static void main(String[] args) {
ImageCache imageCache = new ImageCache();
byte[] image1 = imageCache.getImage("image1.png");
byte[] image2 = imageCache.getImage("image2.png");
System.out.println("Image1 loaded: " + (image1 != null));
System.out.println("Image2 loaded: " + (image2 != null));
}
}
#Java #Training #Medium #WeakHashMap
This media is not supported in your browser
VIEW IN TELEGRAM
Запись нашей сегодняшней встречи -
https://youtu.be/PqW7agFgVts
Огромная благодарность @MrAbhorrent, @vovs03, @Alexander_Gors за участие и подсказки!
Сегодня мы создали консольную игру пинг-понг, в которую можно без проблем поиграть)))
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб канал!
Гит репозиторий с результатом - https://github.com/Oleborn/Ping_Pong_Project
Всем хорошего настроения! 👻
https://youtu.be/PqW7agFgVts
Огромная благодарность @MrAbhorrent, @vovs03, @Alexander_Gors за участие и подсказки!
Сегодня мы создали консольную игру пинг-понг, в которую можно без проблем поиграть)))
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб канал!
Гит репозиторий с результатом - https://github.com/Oleborn/Ping_Pong_Project
Всем хорошего настроения! 👻
IdentityHashMap, отличия от других Map
IdentityHashMap — это специальная реализация интерфейса Map в Java, которая использует оператор == для сравнения ключей и значений вместо метода equals(), который используется в большинстве других реализаций Map. Это означает, что в IdentityHashMap ключи считаются одинаковыми, если они ссылаются на один и тот же объект в памяти, а не если они логически равны.
Отличия от других реализаций Map
Сравнение ключей и значений:
HashMap, TreeMap и другие реализации Map используют метод equals() для сравнения ключей и значений.
IdentityHashMap использует оператор ==, что означает сравнение по ссылке, а не по содержимому.
Производительность:
IdentityHashMap может быть быстрее для некоторых операций, так как оператор == работает быстрее, чем метод equals().
В то же время, IdentityHashMap не гарантирует порядок элементов и не предназначен для использования в случаях, когда важно логическое равенство объектов.
Применение:
IdentityHashMap используется в специализированных случаях, таких как кеширование объектов с уникальными ссылками, когда требуется учитывать именно ссылки, а не содержимое объектов.
Другие реализации, такие как HashMap, подходят для большинства стандартных задач, где важно логическое равенство объектов.
Пример использования
В этом примере видно, что IdentityHashMap хранит два разных элемента для двух разных объектов key1 и key2, даже если их содержимое идентично. В то время как HashMap считает эти объекты одинаковыми из-за использования метода equals() и перезаписывает значение.
Полезные ссылки для более полного ознакомления с IdentityHashMap (спасибо авторам за их кропотливую работу):
https://www.baeldung.com/java-identityhashmap
#Java #Training #Medium #IdentityHashMap
IdentityHashMap — это специальная реализация интерфейса Map в Java, которая использует оператор == для сравнения ключей и значений вместо метода equals(), который используется в большинстве других реализаций Map. Это означает, что в IdentityHashMap ключи считаются одинаковыми, если они ссылаются на один и тот же объект в памяти, а не если они логически равны.
Отличия от других реализаций Map
Сравнение ключей и значений:
HashMap, TreeMap и другие реализации Map используют метод equals() для сравнения ключей и значений.
IdentityHashMap использует оператор ==, что означает сравнение по ссылке, а не по содержимому.
Производительность:
IdentityHashMap может быть быстрее для некоторых операций, так как оператор == работает быстрее, чем метод equals().
В то же время, IdentityHashMap не гарантирует порядок элементов и не предназначен для использования в случаях, когда важно логическое равенство объектов.
Применение:
IdentityHashMap используется в специализированных случаях, таких как кеширование объектов с уникальными ссылками, когда требуется учитывать именно ссылки, а не содержимое объектов.
Другие реализации, такие как HashMap, подходят для большинства стандартных задач, где важно логическое равенство объектов.
Пример использования
import java.util.IdentityHashMap;
import java.util.Map;
public class IdentityHashMapExample {
public static void main(String[] args) {
Map<String, String> identityMap = new IdentityHashMap<>();
String key1 = new String("key");
String key2 = new String("key");
identityMap.put(key1, "Value 1");
identityMap.put(key2, "Value 2");
System.out.println("Size of IdentityHashMap: " + identityMap.size()); // Output: 2
System.out.println("Value for key1: " + identityMap.get(key1)); // Output: Value 1
System.out.println("Value for key2: " + identityMap.get(key2)); // Output: Value 2
// Compare with HashMap
Map<String, String> hashMap = new HashMap<>();
hashMap.put(key1, "Value 1");
hashMap.put(key2, "Value 2");
System.out.println("Size of HashMap: " + hashMap.size()); // Output: 1
}
}
В этом примере видно, что IdentityHashMap хранит два разных элемента для двух разных объектов key1 и key2, даже если их содержимое идентично. В то время как HashMap считает эти объекты одинаковыми из-за использования метода equals() и перезаписывает значение.
Полезные ссылки для более полного ознакомления с IdentityHashMap (спасибо авторам за их кропотливую работу):
https://www.baeldung.com/java-identityhashmap
#Java #Training #Medium #IdentityHashMap
Baeldung
Java IdentityHashMap Class and Its Use Cases | Baeldung
Learn how to use IdentityHashMap in Java