Java for Beginner
Сегодня в 18:00 по МСК, @Alexander_Gors расскажет и покажет как решать задачи на Codewar! 😎 Присоединяйтесь будет интересно!!! Ждем каждого!
Встреча перенесена на 19:00!!! По техническим причинам!)
Основные методы LinkedTransferQueue и примеры использования
put(E e):
Вставляет элемент в очередь. Этот метод никогда не блокируется в LinkedTransferQueue, так как очередь не имеет ограничений на размер.
offer(E e):
Вставляет элемент в очередь, возвращает true, если элемент был успешно вставлен.
transfer(E e):
Вставляет элемент в очередь и блокируется до тех пор, пока элемент не будет извлечен другим потоком.
tryTransfer(E e):
Пытается вставить элемент в очередь, не блокируя, если нет ожидающего потребителя. Возвращает true, если элемент был передан.
tryTransfer(E e, long timeout, TimeUnit unit):
Пытается передать элемент, блокируясь в течение указанного времени ожидания, если нет готового потребителя. Возвращает true, если элемент был передан.
take():
Извлекает и удаляет элемент из головы очереди, блокируясь до тех пор, пока элемент не станет доступен.
poll(long timeout, TimeUnit unit):
Пытается извлечь элемент из головы очереди, блокируясь в течение указанного времени ожидания. Возвращает элемент или null, если тайм-аут истек.
remainingCapacity():
Возвращает оставшуюся емкость очереди. Для LinkedTransferQueue всегда возвращает Integer.MAX_VALUE.
hasWaitingConsumer():
Проверяет, есть ли ожидающие потребители.
getWaitingConsumerCount():
Возвращает количество ожидающих потребителей.
Примеры использования LinkedTransferQueue
Производитель-потребитель с передачей данных:
#Java #Training #Medium #LinkedTransferQueue
put(E e):
Вставляет элемент в очередь. Этот метод никогда не блокируется в LinkedTransferQueue, так как очередь не имеет ограничений на размер.
TransferQueue<Integer> queue = new LinkedTransferQueue<>();
queue.put(1); // Вставка элемента в очередь
offer(E e):
Вставляет элемент в очередь, возвращает true, если элемент был успешно вставлен.
boolean success = queue.offer(2); // Вставка элемента, возвращает true
transfer(E e):
Вставляет элемент в очередь и блокируется до тех пор, пока элемент не будет извлечен другим потоком.
queue.transfer(3); // Вставка элемента и блокировка до его извлечения
tryTransfer(E e):
Пытается вставить элемент в очередь, не блокируя, если нет ожидающего потребителя. Возвращает true, если элемент был передан.
boolean transferred = queue.tryTransfer(4); // Пытается передать элемент, не блокируя
tryTransfer(E e, long timeout, TimeUnit unit):
Пытается передать элемент, блокируясь в течение указанного времени ожидания, если нет готового потребителя. Возвращает true, если элемент был передан.
boolean transferredWithTimeout = queue.tryTransfer(5, 1, TimeUnit.SECONDS); // Пытается передать элемент с тайм-аутом
take():
Извлекает и удаляет элемент из головы очереди, блокируясь до тех пор, пока элемент не станет доступен.
Integer element = queue.take(); // Блокирующее извлечение элемента
poll(long timeout, TimeUnit unit):
Пытается извлечь элемент из головы очереди, блокируясь в течение указанного времени ожидания. Возвращает элемент или null, если тайм-аут истек.
Integer polledElement = queue.poll(1, TimeUnit.SECONDS); // Пытается извлечь элемент с тайм-аутом
remainingCapacity():
Возвращает оставшуюся емкость очереди. Для LinkedTransferQueue всегда возвращает Integer.MAX_VALUE.
int capacity = queue.remainingCapacity(); // Возвращает Integer.MAX_VALUE
hasWaitingConsumer():
Проверяет, есть ли ожидающие потребители.
boolean hasConsumers = queue.hasWaitingConsumer(); // Проверяет наличие ожидающих потребителей
getWaitingConsumerCount():
Возвращает количество ожидающих потребителей.
int consumerCount = queue.getWaitingConsumerCount(); // Возвращает количество ожидающих потребителей
Примеры использования LinkedTransferQueue
Производитель-потребитель с передачей данных:
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
public class ProducerConsumerExample {
public static void main(String[] args) {
TransferQueue<Integer> queue = new LinkedTransferQueue<>();
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
System.out.println("Produced: " + i);
queue.transfer(i);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
Integer item = queue.take();
System.out.println("Consumed: " + item);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
#Java #Training #Medium #LinkedTransferQueue
Пример использования методов tryTransfer и poll с тайм-аутами.
Использование LinkedTransferQueue для синхронизации потоков, обеспечивая передачу сигналов между ними.
#Java #Training #Medium #LinkedTransferQueue
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TransferQueue;
public class TimeoutExample {
public static void main(String[] args) {
TransferQueue<Integer> queue = new LinkedTransferQueue<>();
new Thread(() -> {
try {
boolean transferred = queue.tryTransfer(1, 1, TimeUnit.SECONDS);
if (transferred) {
System.out.println("Element transferred");
} else {
System.out.println("Failed to transfer element");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
new Thread(() -> {
try {
Integer element = queue.poll(2, TimeUnit.SECONDS);
if (element != null) {
System.out.println("Element retrieved: " + element);
} else {
System.out.println("No element retrieved");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
}
}
Использование LinkedTransferQueue для синхронизации потоков, обеспечивая передачу сигналов между ними.
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
public class ThreadSyncExample {
public static void main(String[] args) {
TransferQueue<String> queue = new LinkedTransferQueue<>();
Thread thread1 = new Thread(() -> {
try {
queue.transfer("Signal from Thread 1");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread thread2 = new Thread(() -> {
try {
String signal = queue.take();
System.out.println("Received: " + signal);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
thread1.start();
thread2.start();
}
}
#Java #Training #Medium #LinkedTransferQueue
Встреча создана.
Сегодня мы будем вгрызаться в алгоритмические задачи и побеждать их. Стоит отметить что подготовленная задача только одна, а остальные будут попадаться случайно.
Те кто хочет поболтать вне темы до записи в 19:00 , можете присоединяться по ссылке: https://telemost.yandex.ru/j/45504529681360
Сегодня мы будем вгрызаться в алгоритмические задачи и побеждать их. Стоит отметить что подготовленная задача только одна, а остальные будут попадаться случайно.
Те кто хочет поболтать вне темы до записи в 19:00 , можете присоединяться по ссылке: https://telemost.yandex.ru/j/45504529681360
telemost.yandex.ru
Яндекс.Телемост
Видеовстречи по ссылке. Собирайте в Телемосте рабочие конференции или встречайтесь с друзьями. Встречи не ограничены по времени. Можно скачать Телемост для Windows или macOS.
PriorityBlockingQueue, особенности и внутреннее устройство
PriorityBlockingQueue — это реализация интерфейса BlockingQueue в Java, который поддерживает элементы с приоритетом. Очередь использует естественный порядок элементов или компаратор для их упорядочивания. В отличие от обычной очереди, в которой элементы обрабатываются в порядке их вставки, PriorityBlockingQueue позволяет извлекать элементы в соответствии с их приоритетами.
Особенности PriorityBlockingQueue
Приоритетный порядок:
Элементы в очереди сортируются по их естественному порядку или по заданному компаратору.
Высокоприоритетные элементы будут извлекаться первыми.
Неблокирующие операции вставки:
Методы put и offer не блокируются, так как очередь не имеет ограничений на размер.
Блокирующие операции извлечения:
Методы take и poll блокируются, если очередь пуста, до тех пор, пока элемент не станет доступным.
Многопоточность:
PriorityBlockingQueue является потокобезопасной и поддерживает конкурентный доступ из множества потоков.
Без ограничения размера:
Очередь динамически расширяется по мере необходимости и не имеет фиксированного размера.
Внутреннее устройство PriorityBlockingQueue
Базовая структура данных:
Основой PriorityBlockingQueue является массив, который представляет собой бинарную кучу (минимальную кучу).
Бинарная куча — это полное бинарное дерево, где каждый узел меньше или равен своим потомкам (для минимальной кучи).
Синхронизация:
Очередь использует методы синхронизации для обеспечения потокобезопасности.
Основные операции, такие как вставка и удаление элементов, синхронизированы для предотвращения гонок.
Алгоритмы вставки и извлечения:
При вставке нового элемента, он добавляется в конец массива, а затем "плавает вверх" по дереву, чтобы найти свое правильное место.
При извлечении элемента, корневой элемент (с минимальным значением) удаляется, и последний элемент массива перемещается на его место, затем "тонет" вниз, чтобы восстановить свойства кучи.
Пример кода внутреннего устройства
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://for-each.dev/lessons/b/-java-priority-blocking-queue
https://www.baeldung.com/java-priority-blocking-queue
#Java #Training #Medium #PriorityBlockingQueue
PriorityBlockingQueue — это реализация интерфейса BlockingQueue в Java, который поддерживает элементы с приоритетом. Очередь использует естественный порядок элементов или компаратор для их упорядочивания. В отличие от обычной очереди, в которой элементы обрабатываются в порядке их вставки, PriorityBlockingQueue позволяет извлекать элементы в соответствии с их приоритетами.
Особенности PriorityBlockingQueue
Приоритетный порядок:
Элементы в очереди сортируются по их естественному порядку или по заданному компаратору.
Высокоприоритетные элементы будут извлекаться первыми.
Неблокирующие операции вставки:
Методы put и offer не блокируются, так как очередь не имеет ограничений на размер.
Блокирующие операции извлечения:
Методы take и poll блокируются, если очередь пуста, до тех пор, пока элемент не станет доступным.
Многопоточность:
PriorityBlockingQueue является потокобезопасной и поддерживает конкурентный доступ из множества потоков.
Без ограничения размера:
Очередь динамически расширяется по мере необходимости и не имеет фиксированного размера.
Внутреннее устройство PriorityBlockingQueue
Базовая структура данных:
Основой PriorityBlockingQueue является массив, который представляет собой бинарную кучу (минимальную кучу).
Бинарная куча — это полное бинарное дерево, где каждый узел меньше или равен своим потомкам (для минимальной кучи).
Синхронизация:
Очередь использует методы синхронизации для обеспечения потокобезопасности.
Основные операции, такие как вставка и удаление элементов, синхронизированы для предотвращения гонок.
Алгоритмы вставки и извлечения:
При вставке нового элемента, он добавляется в конец массива, а затем "плавает вверх" по дереву, чтобы найти свое правильное место.
При извлечении элемента, корневой элемент (с минимальным значением) удаляется, и последний элемент массива перемещается на его место, затем "тонет" вниз, чтобы восстановить свойства кучи.
Пример кода внутреннего устройства
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueExample {
public static void main(String[] args) throws InterruptedException {
PriorityBlockingQueue<Integer> queue = new PriorityBlockingQueue<>();
// Добавление элементов в очередь
queue.put(10);
queue.put(20);
queue.put(5);
// Извлечение элементов из очереди
System.out.println(queue.take()); // 5
System.out.println(queue.take()); // 10
System.out.println(queue.take()); // 20
}
}
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://for-each.dev/lessons/b/-java-priority-blocking-queue
https://www.baeldung.com/java-priority-blocking-queue
#Java #Training #Medium #PriorityBlockingQueue
for-each.dev
Руководство по PriorityBlockingQueue в Java | for-each.dev
Введение в Java's PriorityBlockingQueue с примерами использования
Как Вы попали к нам на канал?
Anonymous Poll
25%
с Youtube
7%
с Rutube
29%
с сайта JavaRush
18%
с других каналов Telegram
14%
знакомый посоветовал)))
4%
сам нашел по тегам
4%
напишу в комментариях!
Что выведет код?
#Tasks
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueTask {
public static void main(String[] args) throws InterruptedException {
PriorityBlockingQueue<Integer> queue = new PriorityBlockingQueue<>();
queue.add(10);
queue.add(30);
queue.add(20);
queue.add(5);
queue.add(15);
// Основная логика
Thread consumer = new Thread(() -> {
try {
for (int i = 0; i < 3; i++) {
Integer value = queue.take();
System.out.println("Consumed: " + value);
Thread.sleep(50); // задержка для имитации обработки
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
consumer.start();
consumer.join(); // Ожидаем завершения потока
// Выводим оставшиеся элементы в очереди
while (!queue.isEmpty()) {
System.out.println("Remaining: " + queue.poll());
}
}
}
#Tasks
Основные методы PriorityBlockingQueue и примеры использования
put(E e):
Вставляет элемент в очередь. Этот метод никогда не блокируется, так как очередь не имеет ограничений на размер.
offer(E e):
Вставляет элемент в очередь. Возвращает true, если элемент был успешно вставлен.
take():
Извлекает и удаляет элемент с наивысшим приоритетом из головы очереди. Блокируется, если очередь пуста.
poll(long timeout, TimeUnit unit):
Пытается извлечь элемент из головы очереди, блокируясь в течение указанного времени ожидания. Возвращает элемент или null, если тайм-аут истек.
peek():
Возвращает элемент с наивысшим приоритетом, но не удаляет его из очереди. Возвращает null, если очередь пуста.
size():
Возвращает количество элементов в очереди.
contains(Object o):
Проверяет, содержится ли указанный элемент в очереди.
remove(Object o):
Удаляет указанное значение из очереди, если оно присутствует.
Пример использования PriorityBlockingQueue
Обработка задач с приоритетами:
PriorityBlockingQueue можно использовать для реализации планировщика задач, где задачи с высоким приоритетом обрабатываются первыми.
#Java #Training #Medium #PriorityBlockingQueue
put(E e):
Вставляет элемент в очередь. Этот метод никогда не блокируется, так как очередь не имеет ограничений на размер.
PriorityBlockingQueue<Integer> queue = new PriorityBlockingQueue<>();
queue.put(15); // Вставка элемента в очередь
offer(E e):
Вставляет элемент в очередь. Возвращает true, если элемент был успешно вставлен.
boolean success = queue.offer(25); // Вставка элемента, возвращает true
take():
Извлекает и удаляет элемент с наивысшим приоритетом из головы очереди. Блокируется, если очередь пуста.
Integer element = queue.take(); // Блокирующее извлечение элемента
poll(long timeout, TimeUnit unit):
Пытается извлечь элемент из головы очереди, блокируясь в течение указанного времени ожидания. Возвращает элемент или null, если тайм-аут истек.
Integer polledElement = queue.poll(1, TimeUnit.SECONDS); // Пытается извлечь элемент с тайм-аутом
peek():
Возвращает элемент с наивысшим приоритетом, но не удаляет его из очереди. Возвращает null, если очередь пуста.
Integer peekedElement = queue.peek(); // Просмотр элемента без его удаления
size():
Возвращает количество элементов в очереди.
int size = queue.size(); // Получение размера очереди
contains(Object o):
Проверяет, содержится ли указанный элемент в очереди.
boolean contains = queue.contains(15); // Проверка наличия элемента в очереди
remove(Object o):
Удаляет указанное значение из очереди, если оно присутствует.
boolean removed = queue.remove(25); // Удаление элемента из очереди
Пример использования PriorityBlockingQueue
Обработка задач с приоритетами:
PriorityBlockingQueue можно использовать для реализации планировщика задач, где задачи с высоким приоритетом обрабатываются первыми.
import java.util.concurrent.PriorityBlockingQueue;
class Task implements Comparable<Task> {
private int priority;
private String name;
public Task(int priority, String name) {
this.priority = priority;
this.name = name;
}
@Override
public int compareTo(Task other) {
return Integer.compare(this.priority, other.priority);
}
@Override
public String toString() {
return "Task{name='" + name + "', priority=" + priority + '}';
}
}
public class TaskScheduler {
public static void main(String[] args) throws InterruptedException {
PriorityBlockingQueue<Task> taskQueue = new PriorityBlockingQueue<>();
taskQueue.put(new Task(3, "Low priority task"));
taskQueue.put(new Task(1, "High priority task"));
taskQueue.put(new Task(2, "Medium priority task"));
while (!taskQueue.isEmpty()) {
Task task = taskQueue.take();
System.out.println("Processing " + task);
}
}
}
#Java #Training #Medium #PriorityBlockingQueue
Запись нашей вчерашней встречи -
https://youtu.be/2MVB0HK38ys
https://rutube.ru/video/45b0ddb0dd703ef3a8242154593d0898/
Спасибо тем кто смог прийти, за участие и подсказки!
@andrew_dev09 отдельный респект за то, что не постеснялся рассказать о паттернах)
На встрече, мы рассмотрели на примерах поведенческие паттерны проектирования:
- Цепочка обязанностей (Chain of Responsibility)
- Команда (Command, Transaction)
- Итератор (Iterator)
- Посредник (Mediator)
- Снимок (Memento)
- Наблюдатель (Observer)
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!
Гит репозиторий с результатом - https://github.com/Oleborn/PatternsOfCoding
Всем доброго утра и легкой рабочей недели! 🫡✌️
https://youtu.be/2MVB0HK38ys
https://rutube.ru/video/45b0ddb0dd703ef3a8242154593d0898/
Спасибо тем кто смог прийти, за участие и подсказки!
@andrew_dev09 отдельный респект за то, что не постеснялся рассказать о паттернах)
На встрече, мы рассмотрели на примерах поведенческие паттерны проектирования:
- Цепочка обязанностей (Chain of Responsibility)
- Команда (Command, Transaction)
- Итератор (Iterator)
- Посредник (Mediator)
- Снимок (Memento)
- Наблюдатель (Observer)
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!
Гит репозиторий с результатом - https://github.com/Oleborn/PatternsOfCoding
Всем доброго утра и легкой рабочей недели! 🫡✌️
YouTube
Поведенческие паттерны проектирования на Java. Онлайн встреча от 19.08.2024
Онлайн встреча нашего канала, которую мы провели совместно с подписчиками.
Сегодня мы рассмотрели на примерах следующие поведенческие паттерны проектирования:
- Цепочка обязанностей (Chain of Responsibility)
- Команда (Command, Transaction)
- Итератор (Iterator)…
Сегодня мы рассмотрели на примерах следующие поведенческие паттерны проектирования:
- Цепочка обязанностей (Chain of Responsibility)
- Команда (Command, Transaction)
- Итератор (Iterator)…
Media is too big
VIEW IN TELEGRAM
Для тех кто не смог победить блокировку Youtube и не желает заходить в Rutube выкладываю видео тут!
Смотрите на здоровье) 🫡
#online_meeting
Смотрите на здоровье) 🫡
#online_meeting
HashSet, особенности и внутреннее устройство
HashSet — это одна из наиболее часто используемых реализаций интерфейса Set в Java. Она обеспечивает хранение уникальных элементов и не гарантирует их порядок. Основные преимущества HashSet включают быструю вставку, удаление и проверку на наличие элемента, что делает его предпочтительным выбором для множества задач, связанных с уникальными данными.
Особенности HashSet
Уникальность элементов:
HashSet хранит только уникальные элементы. Если попытаться добавить дубликат, он будет проигнорирован.
Отсутствие упорядоченности:
В отличие от некоторых других коллекций, таких как TreeSet, HashSet не гарантирует порядка элементов. Порядок может изменяться с течением времени.
Производительность:
HashSet обеспечивает быструю производительность операций add, remove, и contains, обычно с временной сложностью O(1), что достигается за счет использования хеш-таблицы.
Разрешение коллизий:
Внутренне HashSet использует механизм разрешения коллизий, что позволяет эффективно справляться с ситуациями, когда два или более различных элемента имеют одинаковый хеш-код.
Не синхронизирован:
HashSet не является потокобезопасным. Если он используется в многопоточной среде, то необходимо явно синхронизировать доступ к нему.
Внутреннее устройство HashSet
Базовая структура данных:
HashSet основан на HashMap, где каждый элемент множества является ключом в HashMap, а значение всегда одно и то же (PRESENT, которое является статической константой).
По сути, HashSet — это оболочка над HashMap, обеспечивающая уникальность элементов за счет использования ключей.
Хеширование и корзины (buckets):
Каждый элемент, добавляемый в HashSet, сначала хешируется. Затем вычисляется индекс корзины (bucket), в которую этот элемент должен быть помещен. Корзина представляет собой связанный список или дерево, хранящее элементы с одинаковыми хеш-кодами.
На основе хеш-кода определяется индекс корзины в массиве корзин.
Если два объекта имеют одинаковый хеш-код, то они попадают в одну и ту же корзину, что приводит к коллизии.
Разрешение коллизий:
В HashMap, а соответственно и в HashSet, используется метод цепочек для разрешения коллизий. Это означает, что в случае коллизии элементы добавляются в связанный список, находящийся в соответствующей корзине.
Если количество элементов в корзине превышает определенный порог (обычно 8), связанный список преобразуется в дерево, что улучшает производительность поиска.
Перестройка (rehashing):
Когда количество элементов в HashSet достигает определенного порога (обычно при заполнении на 75%), происходит перераспределение и увеличение количества корзин, чтобы уменьшить количество коллизий. Это называется перестройкой или rehashing.
Равенство объектов:
Для корректной работы HashSet элементы должны корректно реализовывать методы equals() и hashCode(). Это необходимо для определения уникальности элементов и корректного размещения их в корзинах.
Пример кода внутреннего устройства
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://javarush.com/groups/posts/2147-hashset-v-java
https://ru.hexlet.io/qna/java/questions/kak-rabotaet-hashset-v-java
#Java #Training #Medium #HashSet
HashSet — это одна из наиболее часто используемых реализаций интерфейса Set в Java. Она обеспечивает хранение уникальных элементов и не гарантирует их порядок. Основные преимущества HashSet включают быструю вставку, удаление и проверку на наличие элемента, что делает его предпочтительным выбором для множества задач, связанных с уникальными данными.
Особенности HashSet
Уникальность элементов:
HashSet хранит только уникальные элементы. Если попытаться добавить дубликат, он будет проигнорирован.
Отсутствие упорядоченности:
В отличие от некоторых других коллекций, таких как TreeSet, HashSet не гарантирует порядка элементов. Порядок может изменяться с течением времени.
Производительность:
HashSet обеспечивает быструю производительность операций add, remove, и contains, обычно с временной сложностью O(1), что достигается за счет использования хеш-таблицы.
Разрешение коллизий:
Внутренне HashSet использует механизм разрешения коллизий, что позволяет эффективно справляться с ситуациями, когда два или более различных элемента имеют одинаковый хеш-код.
Не синхронизирован:
HashSet не является потокобезопасным. Если он используется в многопоточной среде, то необходимо явно синхронизировать доступ к нему.
Внутреннее устройство HashSet
Базовая структура данных:
HashSet основан на HashMap, где каждый элемент множества является ключом в HashMap, а значение всегда одно и то же (PRESENT, которое является статической константой).
По сути, HashSet — это оболочка над HashMap, обеспечивающая уникальность элементов за счет использования ключей.
private transient HashMap<E,Object> map;
// Заглушка значения для всех ключей
private static final Object PRESENT = new Object();
Хеширование и корзины (buckets):
Каждый элемент, добавляемый в HashSet, сначала хешируется. Затем вычисляется индекс корзины (bucket), в которую этот элемент должен быть помещен. Корзина представляет собой связанный список или дерево, хранящее элементы с одинаковыми хеш-кодами.
На основе хеш-кода определяется индекс корзины в массиве корзин.
Если два объекта имеют одинаковый хеш-код, то они попадают в одну и ту же корзину, что приводит к коллизии.
Разрешение коллизий:
В HashMap, а соответственно и в HashSet, используется метод цепочек для разрешения коллизий. Это означает, что в случае коллизии элементы добавляются в связанный список, находящийся в соответствующей корзине.
Если количество элементов в корзине превышает определенный порог (обычно 8), связанный список преобразуется в дерево, что улучшает производительность поиска.
Перестройка (rehashing):
Когда количество элементов в HashSet достигает определенного порога (обычно при заполнении на 75%), происходит перераспределение и увеличение количества корзин, чтобы уменьшить количество коллизий. Это называется перестройкой или rehashing.
Равенство объектов:
Для корректной работы HashSet элементы должны корректно реализовывать методы equals() и hashCode(). Это необходимо для определения уникальности элементов и корректного размещения их в корзинах.
Пример кода внутреннего устройства
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
// Добавление элементов
set.add("Apple");
set.add("Banana");
set.add("Orange");
// Попытка добавить дубликат
boolean isAdded = set.add("Apple"); // Вернет false, так как "Apple" уже существует
// Вывод элементов
for (String fruit : set) {
System.out.println(fruit);
}
}
}
Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://javarush.com/groups/posts/2147-hashset-v-java
https://ru.hexlet.io/qna/java/questions/kak-rabotaet-hashset-v-java
#Java #Training #Medium #HashSet
JavaRush
HashSet и Set в Java
Класс HashSet реализует интерфейс Set, основан на хэш-таблице, а также поддерживается с помощью экземпляра HashMap
Что выведет код?
#Tasks
import java.util.HashSet;
public class HashSetTask {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("orange");
set.add("apple");
set.add("grape");
set.remove("banana");
set.add("pear");
System.out.println("Set size: " + set.size());
if (set.contains("orange")) {
set.remove("orange");
set.add("orange");
}
for (String fruit : set) {
System.out.print(fruit + " ");
}
}
}
#Tasks