Java for Beginner
674 subscribers
555 photos
156 videos
12 files
848 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
LinkedHashSet

LinkedHashSet — это одна из реализаций интерфейса Set в Java, которая сочетает в себе преимущества HashSet и LinkedList. Как и HashSet, LinkedHashSet гарантирует уникальность элементов, но в отличие от HashSet, он сохраняет порядок вставки элементов. Это делает его полезным в ситуациях, когда важно сохранить последовательность добавления элементов, но при этом необходимо гарантировать их уникальность.

Отличие от HashSet

Порядок элементов:
Основное отличие между LinkedHashSet и HashSet заключается в порядке элементов. В HashSet порядок элементов не гарантируется и может изменяться при выполнении операций с множеством. В LinkedHashSet же порядок элементов всегда соответствует порядку их вставки.

Дополнительные накладные расходы:
За поддержку порядка вставки приходится платить дополнительными накладными расходами на хранение связанного списка, что делает LinkedHashSet немного более ресурсоемким по сравнению с HashSet.

Использование памяти:
Внутри LinkedHashSet требует больше памяти, поскольку кроме данных элементов, он хранит ссылки на предыдущий и следующий элементы, что поддерживает связный список.

Особенности LinkedHashSet

Сохраняемый порядок вставки:
Как упоминалось ранее, порядок элементов в LinkedHashSet соответствует порядку их добавления. Это делает его полезным для реализации кешей, где порядок имеет значение, или для задач, где важна последовательность операций.

Уникальность элементов:
Как и любой другой Set, LinkedHashSet гарантирует, что каждый элемент будет уникальным. При добавлении дубликата он просто игнорируется.

Производительность:
Операции добавления, удаления, и проверки наличия элемента в LinkedHashSet имеют временную сложность O(1), аналогично HashSet. Однако из-за дополнительного управления связным списком, реальная производительность может быть несколько ниже.

Не синхронизирован:
Как и HashSet, LinkedHashSet не является потокобезопасным. Для использования в многопоточной среде доступ к нему необходимо явно синхронизировать.

Внутреннее устройство LinkedHashSet
LinkedHashSet основан на HashMap, но с дополнительным механизмом для поддержания порядка элементов.

Комбинация HashMap и LinkedList:

Внутренне LinkedHashSet использует LinkedHashMap, который сам по себе является расширением HashMap, но с добавлением двусвязного списка для хранения порядка элементов.
Каждая запись в LinkedHashMap содержит три ссылки: на ключ (элемент Set), на следующий элемент и на предыдущий элемент. Это позволяет сохранять итерируемый порядок элементов.

public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, Serializable {
private transient LinkedHashMap<E, Object> map;

// Значение для всех ключей в LinkedHashSet
private static final Object PRESENT = new Object();

public LinkedHashSet() {
map = new LinkedHashMap<>();
}

public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
}


Порядок вставки:

В LinkedHashMap для каждого элемента поддерживается порядок вставки через двусвязный список. Это достигается с помощью дополнительных ссылок в каждом элементе: before и after, указывающих на предыдущий и следующий элементы соответственно.

Пример внутреннего устройства:
Когда вы добавляете элементы в LinkedHashSet, они хранятся в HashMap (в случае LinkedHashSet — в LinkedHashMap), и порядок вставки сохраняется в связном списке.
LinkedHashSet<String> linkedSet = new LinkedHashSet<>();
linkedSet.add("Apple");
linkedSet.add("Banana");
linkedSet.add("Orange");


В данном случае элементы будут храниться и выводиться в порядке: Apple, Banana, Orange.

Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-linkedhashset
https://www.examclouds.com/ru/java/java-core-russian/interface-set

#Java #Training #Medium #LinkedHashSet
Основные методы LinkedHashSet и их применение

add(E e):
Добавляет указанный элемент в множество, если он еще отсутствует.
Возвращает true, если элемент был добавлен, и false, если он уже присутствовал в множестве.
LinkedHashSet<String> set = new LinkedHashSet<>();
boolean added = set.add("Apple"); // Возвращает true
added = set.add("Apple"); // Возвращает false, так как элемент уже существует


remove(Object o):
Удаляет указанный элемент из множества, если он присутствует.
Возвращает true, если элемент был удален, и false, если его не было в множестве.

boolean removed = set.remove("Apple"); // Возвращает true, если "Apple" был удален
removed = set.remove("Banana"); // Возвращает false, если "Banana" не был в наборе


contains(Object o):
Проверяет, присутствует ли указанный элемент в множестве.
Возвращает true, если элемент присутствует, и false в противном случае.

boolean exists = set.contains("Apple"); // Возвращает true, если "Apple" присутствует


isEmpty():
Проверяет, пусто ли множество.
Возвращает true, если множество пусто, и false в противном случае.

boolean isEmpty = set.isEmpty(); // Проверка, пуст ли набор


size():
Возвращает количество элементов в множестве.
int size = set.size(); // Получение размера набора


clear():
Удаляет все элементы из множества. После вызова этого метода множество будет пустым.
set.clear(); // Очищает множество


iterator():
Возвращает итератор для обхода элементов в множестве. Порядок обхода будет соответствовать порядку вставки элементов.
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}


clone():
Создает поверхностную копию LinkedHashSet.
LinkedHashSet<String> clonedSet = (LinkedHashSet<String>) set.clone();



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

Сохранение порядка уникальных элементов:

LinkedHashSet отлично подходит для ситуаций, когда важно сохранить порядок уникальных элементов, например, при обработке пользовательских данных в том порядке, в котором они были введены.
LinkedHashSet<String> orderedSet = new LinkedHashSet<>();
orderedSet.add("One");
orderedSet.add("Two");
orderedSet.add("Three");
orderedSet.add("Two"); // Дубликат будет проигнорирован

for (String item : orderedSet) {
System.out.println(item);
}
// Вывод будет в порядке вставки: One, Two, Three


Реализация простого кеша:

LinkedHashSet может использоваться для реализации кеша, где важно сохранить порядок недавнего использования элементов.
LinkedHashSet<String> cache = new LinkedHashSet<>();
cache.add("Page1");
cache.add("Page2");
cache.add("Page3");

if (cache.size() > 2) {
String first = cache.iterator().next();
cache.remove(first);
}

cache.add("Page4");

System.out.println(cache);
// Вывод: [Page2, Page3, Page4]


Создание списка с исключением дубликатов:

LinkedHashSet позволяет быстро создать список уникальных элементов, сохраняя их порядок.
List<String> listWithDuplicates = Arrays.asList("a", "b", "c", "a", "b");
LinkedHashSet<String> uniqueSet = new LinkedHashSet<>(listWithDuplicates);

System.out.println(uniqueSet); // Вывод: [a, b, c]


#Java #Training #Medium #LinkedHashSet