Коллекции в Java
Глава 3. Set — множества
Методы add, remove, contains
Методы add, remove и contains — это основные операции для добавления, удаления и проверки элементов в Set. Они наследуются от интерфейса Collection, но в Set имеют специфику из-за уникальности элементов.
add(E e): Добавляет элемент в множество, если его еще нет. Возвращает boolean: true, если добавлен (элемент был уникален), false — если уже существовал (дубликат игнорируется).
remove(Object o): Удаляет элемент, если он существует. Возвращает boolean: true, если удален (элемент был), false — если не найден.
contains(Object o): Проверяет, содержит ли множество элемент. Возвращает boolean: true, если есть, false — если нет.
Эти методы работают за O(1) в HashSet/LinkedHashSet (средний случай) и O(log n) в TreeSet.
Общие нюансы:
Все методы используют equals() для сравнения элементов (и hashCode() в Hash-based реализациях).
Null: Разрешен в HashSet/LinkedHashSet (один), но в TreeSet вызывает NullPointerException при сравнении.
Изменение множества: Методы модифицируют Set in-place (на месте).
Thread-safety: Не гарантирована — используйте synchronized версии для многопоточности.
Generics: Set add(Integer) — ошибка компиляции (типобезопасность).
Метод add(E e): Добавление элементов
add() — основной способ наполнения Set. Если элемент уже есть (по equals()), он не добавляется, и возвращается false.
Поведение в реализациях:
HashSet: Добавляет в хэш-таблицу. Если хэш-коллизия, проверяет equals() в цепочке.
LinkedHashSet: Аналогично HashSet, но обновляет ссылки в списке для порядка вставки (только если добавлен).
TreeSet: Добавляет в дерево, сравнивая через compareTo() или Comparator. Если равен 0 — не добавляет.
Возвращаемое значение: true — добавлен (новый), false — уже был.
Исключения: NullPointerException в TreeSet для null; ClassCastException в TreeSet, если элемент не Comparable.
Нюансы:
Если Set полный (редко, так как resizable), может быть OutOfMemoryError.
Для custom объектов: Без правильного equals()/hashCode() может добавить "дубликаты" (по значению, но не по ссылке).
Модификация объекта после добавления: Не изменяйте поля, влияющие на equals/hashCode (например, в HashSet объект может "потеряться").
Пример кода для add():
#Java #для_новичков #beginner #Collections #Set #add #remove #contains
Глава 3. Set — множества
Методы add, remove, contains
Методы add, remove и contains — это основные операции для добавления, удаления и проверки элементов в Set. Они наследуются от интерфейса Collection, но в Set имеют специфику из-за уникальности элементов.
add(E e): Добавляет элемент в множество, если его еще нет. Возвращает boolean: true, если добавлен (элемент был уникален), false — если уже существовал (дубликат игнорируется).
remove(Object o): Удаляет элемент, если он существует. Возвращает boolean: true, если удален (элемент был), false — если не найден.
contains(Object o): Проверяет, содержит ли множество элемент. Возвращает boolean: true, если есть, false — если нет.
Эти методы работают за O(1) в HashSet/LinkedHashSet (средний случай) и O(log n) в TreeSet.
Общие нюансы:
Все методы используют equals() для сравнения элементов (и hashCode() в Hash-based реализациях).
Null: Разрешен в HashSet/LinkedHashSet (один), но в TreeSet вызывает NullPointerException при сравнении.
Изменение множества: Методы модифицируют Set in-place (на месте).
Thread-safety: Не гарантирована — используйте synchronized версии для многопоточности.
Generics: Set add(Integer) — ошибка компиляции (типобезопасность).
Метод add(E e): Добавление элементов
add() — основной способ наполнения Set. Если элемент уже есть (по equals()), он не добавляется, и возвращается false.
Поведение в реализациях:
HashSet: Добавляет в хэш-таблицу. Если хэш-коллизия, проверяет equals() в цепочке.
LinkedHashSet: Аналогично HashSet, но обновляет ссылки в списке для порядка вставки (только если добавлен).
TreeSet: Добавляет в дерево, сравнивая через compareTo() или Comparator. Если равен 0 — не добавляет.
Возвращаемое значение: true — добавлен (новый), false — уже был.
Исключения: NullPointerException в TreeSet для null; ClassCastException в TreeSet, если элемент не Comparable.
Нюансы:
Если Set полный (редко, так как resizable), может быть OutOfMemoryError.
Для custom объектов: Без правильного equals()/hashCode() может добавить "дубликаты" (по значению, но не по ссылке).
Модификация объекта после добавления: Не изменяйте поля, влияющие на equals/hashCode (например, в HashSet объект может "потеряться").
Пример кода для add():
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
// HashSet
Set<String> hashSet = new HashSet<>();
boolean added1 = hashSet.add("Яблоко"); // true
boolean added2 = hashSet.add("Яблоко"); // false (дубликат)
System.out.println(hashSet); // [Яблоко]
// LinkedHashSet
Set<String> linkedSet = new LinkedHashSet<>();
linkedSet.add("Яблоко");
linkedSet.add("Банан");
linkedSet.add("Яблоко"); // false
System.out.println(linkedSet); // [Яблоко, Банан] — порядок вставки
// TreeSet
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(5);
treeSet.add(1);
treeSet.add(5); // false
System.out.println(treeSet); // [1, 5] — отсортировано
}
}
Вывод показывает уникальность и особенности каждой реализации.
#Java #для_новичков #beginner #Collections #Set #add #remove #contains
👍5
Метод remove(Object o): Удаление элементов
remove() удаляет элемент, если он найден по equals(), и возвращает true/false.
Поведение в реализациях:
HashSet: Находит по хэшу, затем equals() — O(1).
LinkedHashSet: Аналогично, плюс обновляет ссылки списка.
TreeSet: Ищет по compareTo() — O(log n), удаляет узел дерева.
Возвращаемое значение: true — удален, false — не найден.
Исключения: NullPointerException в TreeSet для null; ClassCastException, если тип не совместим.
Нюансы:
Аргумент Object: Можно удалять по объекту любого типа, но сравнивает equals().
После remove: Размер уменьшается, итераторы обновляются.
Для custom: Зависит от equals().
Пример кода для remove():
Метод contains(Object o): Проверка наличия
contains() проверяет, есть ли элемент в Set по equals().
Поведение в реализациях:
HashSet: O(1) — хэш + equals().
LinkedHashSet: O(1), но с overhead списка.
TreeSet: O(log n) — поиск в дереве.
Возвращаемое значение: true — есть, false — нет.
Исключения: Аналогично remove: NPE в TreeSet для null.
Нюансы:
Быстрее, чем в List (O(n)), идеально для проверок уникальности.
Для больших Set: HashSet fastest.
Пример кода для contains():
Полезные советы для новичков
add для уникальности: Используйте возвращаемое значение для логики (if (!set.add(e)) { "Дубликат!"; }).
remove/contains для null: Тестируйте — в HashSet работает, в TreeSet — нет.
Custom объекты: Переопределяйте equals/hashCode (IDE: Generate → equals() and hashCode()).
Эффективность: Для частых contains — HashSet; для сортировки — TreeSet.
Комбинируйте: Set для фильтра, затем List для порядка.
Ошибки: ClassCastException в TreeSet без Comparable; ConcurrentModification при модификации в цикле (используйте Iterator).
#Java #для_новичков #beginner #Collections #Set #add #remove #contains
remove() удаляет элемент, если он найден по equals(), и возвращает true/false.
Поведение в реализациях:
HashSet: Находит по хэшу, затем equals() — O(1).
LinkedHashSet: Аналогично, плюс обновляет ссылки списка.
TreeSet: Ищет по compareTo() — O(log n), удаляет узел дерева.
Возвращаемое значение: true — удален, false — не найден.
Исключения: NullPointerException в TreeSet для null; ClassCastException, если тип не совместим.
Нюансы:
Аргумент Object: Можно удалять по объекту любого типа, но сравнивает equals().
После remove: Размер уменьшается, итераторы обновляются.
Для custom: Зависит от equals().
Пример кода для remove():
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<String> fruits = new HashSet<>();
fruits.add("Яблоко");
fruits.add("Банан");
boolean removed1 = fruits.remove("Яблоко"); // true
boolean removed2 = fruits.remove("Апельсин"); // false (не найден)
System.out.println(fruits); // [Банан]
}
}
Аналогично для других реализаций: В TreeSet remove сохраняет сортировку.
Метод contains(Object o): Проверка наличия
contains() проверяет, есть ли элемент в Set по equals().
Поведение в реализациях:
HashSet: O(1) — хэш + equals().
LinkedHashSet: O(1), но с overhead списка.
TreeSet: O(log n) — поиск в дереве.
Возвращаемое значение: true — есть, false — нет.
Исключения: Аналогично remove: NPE в TreeSet для null.
Нюансы:
Быстрее, чем в List (O(n)), идеально для проверок уникальности.
Для больших Set: HashSet fastest.
Пример кода для contains():
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<String> fruits = new HashSet<>();
fruits.add("Яблоко");
System.out.println(fruits.contains("Яблоко")); // true
System.out.println(fruits.contains("Банан")); // false
}
}
Полезные советы для новичков
add для уникальности: Используйте возвращаемое значение для логики (if (!set.add(e)) { "Дубликат!"; }).
remove/contains для null: Тестируйте — в HashSet работает, в TreeSet — нет.
Custom объекты: Переопределяйте equals/hashCode (IDE: Generate → equals() and hashCode()).
Эффективность: Для частых contains — HashSet; для сортировки — TreeSet.
Комбинируйте: Set для фильтра, затем List для порядка.
Ошибки: ClassCastException в TreeSet без Comparable; ConcurrentModification при модификации в цикле (используйте Iterator).
#Java #для_новичков #beginner #Collections #Set #add #remove #contains
👍5
Что выведет код?
#Tasks
import java.util.*;
public class Task131025 {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
String s1 = "Hello";
String s2 = new String("Hello");
String s3 = s2.intern();
set.add(s1);
set.add(s2);
set.add(s3);
set.remove(s1);
set.remove(s3);
System.out.println(set.size());
System.out.println(set.contains("Hello"));
}
}
#Tasks
👍2
👍2
Вопрос с собеседований
Что такое deadlock?🤓
Ответ:
Deadlock (взаимная блокировка) — ситуация, когда несколько потоков ждут ресурсы друг друга и никто не может продолжить работу.
Например, поток А захватил ресурс 1 и ждёт ресурс 2, а поток B — наоборот.
Избежать можно правильным порядком захвата или таймаутами.
#собеседование
Что такое deadlock?
Ответ:
Deadlock
Например, поток А захватил ресурс 1 и ждёт ресурс 2, а поток B — наоборот.
Избежать можно правильным порядком захвата или таймаутами.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
Антонин Свобода (14 октября 1907 г. – 18 мая 1980 г.) – чешский учёный в области вычислительной техники, математик и инженер. Он считается одним из пионеров конструирования отказоустойчивых компьютерных систем и разработчиком первой чешской ЭВМ SAPO.
1957 — на базе Лондонской компьютерной группы и неформального клуба учёных основано Британское компьютерное общество. Первым президентом стал Морис Уилкс.
#Biography #Birth_Date #Events #14Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Что лучше, работа в офисе или удаленка?
Anonymous Poll
64%
Удаленка на 100% лучше - захотел поспал, захотел поработал. Не надо никуда ходить.
36%
Офис лучше. Живое общение, бесплатные печеньки и спортзал. И дома чисто.
Реактивное программирование
Управление потоками в Reactor: Schedulers
Schedulers — часть Reactor Core, они интегрируют с Java's ExecutorService, но абстрагируют детали: вы выбираете тип, а Reactor управляет жизненным циклом. По умолчанию Reactor использует Schedulers.parallel() для вычислений, но вы можете переключать с помощью операторов publishOn (для downstream) и subscribeOn (для upstream). Это даёт контроль: CPU-bound задачи на параллельных потоках, IO-bound — на эластичных. Давайте разберём типы schedulers, операторы и примеры — пробуйте в коде с reactor-core.
Типы Schedulers: выбор под задачу
Reactor предоставляет готовые планировщики для разных сценариев. Каждый — фабрика потоков с настройками (размер пула, демонизация).
- parallel(): Для CPU-bound задач (расчёты). Фиксированный пул = кол-во CPU ядер. Не демоны — ждёт завершения. Идеален для map с тяжёлыми вычислениями.
- boundedElastic(): Для IO-bound (сеть, файлы, БД) с блокирующими операциями. Эластичный пул: до 10*CPU, но переиспользует. Демоны — приложение не ждёт. Полезен, если в лямбде "грязный" код (sleep, blocking IO).
- single(): Один поток для всех задач. Для последовательных операций, где параллелизм не нужен (тесты, простые цепочки).
- immediate(): Выполняет на текущем потоке. Для синхронных тестов или когда асинхронность не требуется.
- fromExecutor(Executor): Кастомный из вашего пула.
Пример создания:
Операторы для переключения: publishOn и subscribeOn
- publishOn(Scheduler): Переключает downstream (операции после него) на указанный scheduler. Влияет на onNext, map, filter и т.д. после точки.
- subscribeOn(Scheduler): Переключает upstream (источник и подписку) на scheduler. Влияет на весь поток от subscribe().
Пример комбинации:
Почему важно? Без schedulers все на default (parallel), но IO может заблокировать CPU-потоки. PublishOn изолирует блокирующие части, subscribeOn — для источников (например, blocking чтение файла на отдельном потоке).
Управление контекстом и параллелизмом
Schedulers помогают с контекстом: в Reactor есть Context для хранения данных (как ThreadLocal, но реактивный). Операторы как withScheduler сохраняют его.
Для параллелизма: в flatMap добавьте concurrency: flatMap(func, concurrency, prefetch), где concurrency — max параллельных подпотоков, prefetch — буфер.
Пример с параллелизмом:
#Java #middle #Reactor #WebClient #Schedulers
Управление потоками в Reactor: Schedulers
Schedulers — часть Reactor Core, они интегрируют с Java's ExecutorService, но абстрагируют детали: вы выбираете тип, а Reactor управляет жизненным циклом. По умолчанию Reactor использует Schedulers.parallel() для вычислений, но вы можете переключать с помощью операторов publishOn (для downstream) и subscribeOn (для upstream). Это даёт контроль: CPU-bound задачи на параллельных потоках, IO-bound — на эластичных. Давайте разберём типы schedulers, операторы и примеры — пробуйте в коде с reactor-core.
Типы Schedulers: выбор под задачу
Reactor предоставляет готовые планировщики для разных сценариев. Каждый — фабрика потоков с настройками (размер пула, демонизация).
- parallel(): Для CPU-bound задач (расчёты). Фиксированный пул = кол-во CPU ядер. Не демоны — ждёт завершения. Идеален для map с тяжёлыми вычислениями.
- boundedElastic(): Для IO-bound (сеть, файлы, БД) с блокирующими операциями. Эластичный пул: до 10*CPU, но переиспользует. Демоны — приложение не ждёт. Полезен, если в лямбде "грязный" код (sleep, blocking IO).
- single(): Один поток для всех задач. Для последовательных операций, где параллелизм не нужен (тесты, простые цепочки).
- immediate(): Выполняет на текущем потоке. Для синхронных тестов или когда асинхронность не требуется.
- fromExecutor(Executor): Кастомный из вашего пула.
Пример создания:
import reactor.core.scheduler.Schedulers;
Schedulers.parallel(); // Готов к использованию
Schedulers не создают потоки заранее — ленивые, как Mono/Flux.
Операторы для переключения: publishOn и subscribeOn
- publishOn(Scheduler): Переключает downstream (операции после него) на указанный scheduler. Влияет на onNext, map, filter и т.д. после точки.
- subscribeOn(Scheduler): Переключает upstream (источник и подписку) на scheduler. Влияет на весь поток от subscribe().
Пример комбинации:
import reactor.core.publisher.Flux;
import java.time.Duration;
Flux<Integer> flux = Flux.range(1, 3)
.map(i -> { // На subscribeOn
System.out.println("Map1 на потоке: " + Thread.currentThread().getName());
return i * 10;
})
.publishOn(Schedulers.boundedElastic()) // Переключаем downstream
.delayElements(Duration.ofSeconds(1)) // На boundedElastic
.map(i -> { // На boundedElastic
System.out.println("Map2 на потоке: " + Thread.currentThread().getName());
return i + 1;
});
flux.subscribeOn(Schedulers.single()) // Upstream на single
.subscribe(System.out::println);
Вывод покажет: Map1 на "single-1", delay и Map2 на "boundedElastic-X". Это асинхронно: основной поток не блокируется.
Почему важно? Без schedulers все на default (parallel), но IO может заблокировать CPU-потоки. PublishOn изолирует блокирующие части, subscribeOn — для источников (например, blocking чтение файла на отдельном потоке).
Управление контекстом и параллелизмом
Schedulers помогают с контекстом: в Reactor есть Context для хранения данных (как ThreadLocal, но реактивный). Операторы как withScheduler сохраняют его.
Для параллелизма: в flatMap добавьте concurrency: flatMap(func, concurrency, prefetch), где concurrency — max параллельных подпотоков, prefetch — буфер.
Пример с параллелизмом:
Flux.range(1, 10)
.flatMap(i -> Mono.just(i).delayElement(Duration.ofMillis(100)), 2) // Max 2 параллельно
.subscribeOn(Schedulers.parallel())
.blockLast(); // Для теста, в prod не блокируйте!
Это ограничивает: не 10 задержек сразу, а по 2.
#Java #middle #Reactor #WebClient #Schedulers
👍2
Практические советы и подводные камни
- Диагностика: используйте doOnNext(() -> Thread.currentThread().getName()) для логирования потоков.
- Shutdown: Schedulers.shutdownNow() для cleanup, но в Spring — автоматом.
- проблема: blocking в parallel() — заблокирует все CPU; всегда publishOn(boundedElastic()) перед blocking.
- Оптимизация: для веб — WebFlux использует Schedulers.default() на Netty event-loop (для IO).
- Тестирование: VirtualTimeScheduler для симуляции времени в StepVerifier.
В практике: в микросервисах — subscribeOn(parallel()) для вычислений, publishOn(boundedElastic()) для БД-запросов.
Реактивные API-запросы с WebClient
WebClient — declarative: строите запрос, получаете Mono/Flux с ответом. Под капотом — Netty или HttpClient для IO, с Schedulers.boundedElastic() по умолчанию. Давайте разберём создание, методы (GET/POST), обработку и примеры — добавьте spring-webflux в зависимости и пробуйте.
Создание и базовая настройка WebClient
WebClient.builder() для кастомизации: baseUrl, headers, client (Netty/HttpClient).
Пример:
Реактивные запросы: GET, POST и обработка
- GET: retrieve() возвращает Mono<ResponseEntity> или Flux для стриминга.
- POST: bodyValue() для данных, exchange() для полного контроля.
Пример GET с Mono:
Пример POST с Flux:
Обработка ответов и ошибок
Retrieve() даёт bodyToMono/Flux, onStatus для ошибок (4xx/5xx).
Пример с обработкой:
Практические советы и подводные камни
- Таймауты: client.mutate().clientConnector(new ReactorClientHttpConnector(HttpClient.create().responseTimeout(Duration.ofSeconds(5)))).build();
- HTTPS: автоматом, но настройте trustStore если нужно.
- Тестирование: WebClient с mock (WireMock) и StepVerifier.
В практике: в Spring Boot контроллер вызывает WebClient для агрегации от сервисов — асинхронно, без ожидания.
#Java #middle #Reactor #WebClient #Schedulers
- Диагностика: используйте doOnNext(() -> Thread.currentThread().getName()) для логирования потоков.
- Shutdown: Schedulers.shutdownNow() для cleanup, но в Spring — автоматом.
- проблема: blocking в parallel() — заблокирует все CPU; всегда publishOn(boundedElastic()) перед blocking.
- Оптимизация: для веб — WebFlux использует Schedulers.default() на Netty event-loop (для IO).
- Тестирование: VirtualTimeScheduler для симуляции времени в StepVerifier.
В практике: в микросервисах — subscribeOn(parallel()) для вычислений, publishOn(boundedElastic()) для БД-запросов.
Реактивные API-запросы с WebClient
WebClient — declarative: строите запрос, получаете Mono/Flux с ответом. Под капотом — Netty или HttpClient для IO, с Schedulers.boundedElastic() по умолчанию. Давайте разберём создание, методы (GET/POST), обработку и примеры — добавьте spring-webflux в зависимости и пробуйте.
Создание и базовая настройка WebClient
WebClient.builder() для кастомизации: baseUrl, headers, client (Netty/HttpClient).
Пример:
import org.springframework.web.reactive.function.client.WebClient;
WebClient client = WebClient.builder()
.baseUrl("https://api.example.com")
.defaultHeader("Authorization", "Bearer token")
.build();
Это готово к запросам. Для кодеков (JSON) — добавьте Jackson или Gson.
Реактивные запросы: GET, POST и обработка
- GET: retrieve() возвращает Mono<ResponseEntity> или Flux для стриминга.
- POST: bodyValue() для данных, exchange() для полного контроля.
Пример GET с Mono:
Mono<String> responseMono = client.get()
.uri("/users/{id}", 1) // URI с параметрами
.retrieve()
.bodyToMono(String.class); // Декодируем в String
responseMono.subscribe(System.out::println); // Асинхронно: ответ придёт позже
Для JSON: bodyToMono(User.class) с Jackson.
Пример POST с Flux:
Flux<User> usersFlux = Flux.just(new User("Alice"), new User("Bob"));
Mono<Void> postMono = client.post()
.uri("/users/batch")
.body(usersFlux, User.class) // Тело как Flux
.retrieve()
.bodyToMono(Void.class);
postMono.subscribe(); // Отправка асинхронно
WebClient уважает backpressure: если сервер шлёт Flux (SSE), клиент запрашивает по мере обработки.
С Schedulers: по умолчанию на event-loop, но publishOn для кастом.
Обработка ответов и ошибок
Retrieve() даёт bodyToMono/Flux, onStatus для ошибок (4xx/5xx).
Пример с обработкой:
client.get()
.uri("/data")
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, resp -> Mono.error(new BadRequestException("Ошибка клиента")))
.bodyToFlux(Data.class)
.doOnError(e -> System.err.println("Сбой: " + e)) // Из поста 10
.retry(3) // Retry на сетевые ошибки
.subscribe(data -> process(data));
Это интегрирует с Reactor: ошибки как onError, retry для flaky API.
Для стриминга: bodyToFlux для больших данных, без загрузки всего в память.
Практические советы и подводные камни
- Таймауты: client.mutate().clientConnector(new ReactorClientHttpConnector(HttpClient.create().responseTimeout(Duration.ofSeconds(5)))).build();
- HTTPS: автоматом, но настройте trustStore если нужно.
- Тестирование: WebClient с mock (WireMock) и StepVerifier.
В практике: в Spring Boot контроллер вызывает WebClient для агрегации от сервисов — асинхронно, без ожидания.
#Java #middle #Reactor #WebClient #Schedulers
👍2
Что выведет код?
#Tasks
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.time.Duration;
public class Task141025 {
public static void main(String[] args) {
WebClient webClient = WebClient.builder()
.baseUrl("http://example.com")
.build();
Mono<String> result = webClient.get()
.uri("/api/data")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofMillis(100))
.onErrorResume(throwable -> {
System.out.println("Timeout occurred!");
return Mono.just("Fallback");
})
.flatMap(response -> {
System.out.println("Processing: " + response);
return Mono.just("Processed: " + response);
});
System.out.println("Final: " + result.block());
}
}
#Tasks
👍1
Вопрос с собеседований
Что такое livelock?🤓
Ответ:
Livelock — это ситуация, когда потоки не блокируются, но из-за постоянных изменений состояния они не могут выполнить задачу.
Это похоже на танец: два потока уступают друг другу, но никто не продвигается.
Решение — алгоритмическая корректировка.
#собеседование
Что такое livelock?
Ответ:
Livelock
Это похоже на танец: два потока уступают друг другу, но никто не продвигается.
Решение — алгоритмическая корректировка.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Джон Кеннет Оустерхаут (родился 15 октября 1954 года) — американский учёный-программист, известен как создатель языка Tcl и инструментов Tk, разработчик лог-структурированной файловой системы и системы автоматизированного проектирования VLSI (Magic).
Джилл, Леди Хоар (родилась 15 октября 1933 года) — британский программист, одна из разработчиц первого компилятора для языка ALGOL-60.
1973 — выпущена четвёртая редакция операционной системы UNIX.
1997 — Энди Грин установил новый рекорд скорости для наземного управляемого транспортного средства, развив скорость 1227,986 км/ч на автомобиле Thrust SSC.
1998 — начало работы почтового сервиса Почта Mail.ru.
2007 — компания «Intel» заявила о разработке нового процессора для мобильных применений — Intel Atom.
#Biography #Birth_Date #Events #15Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Раздел 6. Коллекции в Java
Глава 3. Set — множества
Практика: В «Библиотеке» создать коллекцию Set для хранения уникальных имён авторов.
Добавлять автора при добавлении книги, проверять уникальность.
Откройте проект «Библиотека»: Запустите IntelliJ IDEA и откройте существующий проект LibraryProject (или как вы его назвали). Убедитесь, что класс Book существует с полями title, author, year, конструктором и методом printDetails() (или аналогичным для вывода).
Импортируйте необходимые пакеты: В файлах, где будете использовать Set, убедитесь, что импортированы java.util.Set и java.util.HashSet (или другая реализация). IDE подскажет, когда вы начнете писать код — используйте Ctrl+Enter для автодобавления импорта.
Выберите реализацию Set: Для этого урока используйте HashSet — это базовая реализация для уникальности без порядка. Если хотите поэкспериментировать, попробуйте LinkedHashSet для сохранения порядка вставки авторов.
Обновление класса Book (если нужно)
Класс Book уже имеет поле author типа String. Если вы не добавили геттер для author, сделайте это сейчас — он понадобится для получения имени автора при добавлении в Set.
Добавьте геттер для author:
Откройте файл Book.java.
Добавьте публичный метод getAuthor(), который возвращает значение поля author.
Это обеспечит инкапсуляцию: внешний код не будет напрямую обращаться к полю.
Создание и интеграция Set для авторов
Теперь добавим множество для уникальных авторов. Мы разместим его в классе, который управляет библиотекой, чтобы оно было общим для всех книг.
Создайте класс Library (если его нет):
В пакете проекта (или в src) щелкните правой кнопкой → New → Java Class.
Назовите класс "Library".
Этот класс будет управлять списком книг и множеством авторов.
Добавьте поле для Set:
В классе Library объявите приватное поле authors типа Set, инициализированное как new HashSet<> (или LinkedHashSet<> для порядка).
Используйте private для инкапсуляции — множество не должно быть доступно напрямую извне.
Добавьте поле для списка книг:
Если вы использовали массив Book[], перенесите его в класс Library как приватное поле (Book[] books = new Book[10]; или аналогично).
Добавьте переменную для отслеживания текущего количества книг (int bookCount = 0;), чтобы управлять заполнением массива.
Создайте метод для добавления книги:
Добавьте публичный метод addBook(Book book), который:
Проверяет, есть ли место в массиве (если bookCount < books.length).
Добавляет книгу в массив (books[bookCount] = book; bookCount++;).
Получает имя автора из книги (через getAuthor()).
Добавляет имя автора в Set authors (authors.add(authorName);).
Проверяет возвращаемое значение add(): Если true, значит автор новый; если false — автор уже существует (можно вывести сообщение, например, "Автор уже добавлен").
Добавьте метод для вывода уникальных авторов:
Создайте публичный метод printAuthors(), который перебирает Set authors (через for-each цикл) и выводит каждое имя на экран с помощью System.out.println.
Обновите класс Main для тестирования:
Откройте файл Main.java.
Создайте объект Library (Library library = new Library();).
Создайте несколько объектов Book с разными авторами (некоторые с повторяющимися, чтобы проверить уникальность).
Вызовите addBook для каждой книги.
Вызовите printAuthors() — вы должны увидеть уникальный список авторов без дубликатов.
Для проверки: Добавьте книгу с существующим автором и посмотрите, добавится ли он в Set (метод add вернет false).
#Java #для_новичков #beginner #Collections #Set
Глава 3. Set — множества
Практика: В «Библиотеке» создать коллекцию Set для хранения уникальных имён авторов.
Добавлять автора при добавлении книги, проверять уникальность.
Откройте проект «Библиотека»: Запустите IntelliJ IDEA и откройте существующий проект LibraryProject (или как вы его назвали). Убедитесь, что класс Book существует с полями title, author, year, конструктором и методом printDetails() (или аналогичным для вывода).
Импортируйте необходимые пакеты: В файлах, где будете использовать Set, убедитесь, что импортированы java.util.Set и java.util.HashSet (или другая реализация). IDE подскажет, когда вы начнете писать код — используйте Ctrl+Enter для автодобавления импорта.
Выберите реализацию Set: Для этого урока используйте HashSet — это базовая реализация для уникальности без порядка. Если хотите поэкспериментировать, попробуйте LinkedHashSet для сохранения порядка вставки авторов.
Обновление класса Book (если нужно)
Класс Book уже имеет поле author типа String. Если вы не добавили геттер для author, сделайте это сейчас — он понадобится для получения имени автора при добавлении в Set.
Добавьте геттер для author:
Откройте файл Book.java.
Добавьте публичный метод getAuthor(), который возвращает значение поля author.
Это обеспечит инкапсуляцию: внешний код не будет напрямую обращаться к полю.
Создание и интеграция Set для авторов
Теперь добавим множество для уникальных авторов. Мы разместим его в классе, который управляет библиотекой, чтобы оно было общим для всех книг.
Создайте класс Library (если его нет):
В пакете проекта (или в src) щелкните правой кнопкой → New → Java Class.
Назовите класс "Library".
Этот класс будет управлять списком книг и множеством авторов.
Добавьте поле для Set:
В классе Library объявите приватное поле authors типа Set, инициализированное как new HashSet<> (или LinkedHashSet<> для порядка).
Используйте private для инкапсуляции — множество не должно быть доступно напрямую извне.
Добавьте поле для списка книг:
Если вы использовали массив Book[], перенесите его в класс Library как приватное поле (Book[] books = new Book[10]; или аналогично).
Добавьте переменную для отслеживания текущего количества книг (int bookCount = 0;), чтобы управлять заполнением массива.
Создайте метод для добавления книги:
Добавьте публичный метод addBook(Book book), который:
Проверяет, есть ли место в массиве (если bookCount < books.length).
Добавляет книгу в массив (books[bookCount] = book; bookCount++;).
Получает имя автора из книги (через getAuthor()).
Добавляет имя автора в Set authors (authors.add(authorName);).
Проверяет возвращаемое значение add(): Если true, значит автор новый; если false — автор уже существует (можно вывести сообщение, например, "Автор уже добавлен").
Добавьте метод для вывода уникальных авторов:
Создайте публичный метод printAuthors(), который перебирает Set authors (через for-each цикл) и выводит каждое имя на экран с помощью System.out.println.
Обновите класс Main для тестирования:
Откройте файл Main.java.
Создайте объект Library (Library library = new Library();).
Создайте несколько объектов Book с разными авторами (некоторые с повторяющимися, чтобы проверить уникальность).
Вызовите addBook для каждой книги.
Вызовите printAuthors() — вы должны увидеть уникальный список авторов без дубликатов.
Для проверки: Добавьте книгу с существующим автором и посмотрите, добавится ли он в Set (метод add вернет false).
#Java #для_новичков #beginner #Collections #Set
👍1
Тестирование и отладка
После реализации протестируйте, чтобы убедиться в правильной работе уникальности.
Запустите проект:
Правой кнопкой на Main.java → Run 'Main.main()'.
В консоли увидите вывод уникальных авторов. Убедитесь, что дубликаты авторов не появляются в списке.
Проверьте уникальность:
Добавьте две книги с одним автором — в Set должно быть только одно имя.
Попробуйте добавить null как автора (если поле author позволяет) — проверьте поведение Set (HashSet позволит один null).
Отладка:
Установите breakpoint в методе addBook перед authors.add() и после — шагайте (F8) и смотрите, меняется ли размер Set.
Если ошибки: NullPointerException (если Set не инициализировано), ArrayIndexOutOfBoundsException (если массив переполнен) — добавьте проверку на размер.
В консоли выводите сообщения, например, если add вернул false: "Автор [name] уже существует".
Эксперименты:
Измените реализацию Set на LinkedHashSet — проверьте, сохраняется ли порядок добавления авторов.
Попробуйте TreeSet — добавьте Comparator, если нужно сортировать авторов по алфавиту (TreeSet требует Comparable для элементов).
Полезные советы для новичков
Инициализация Set: Всегда инициализируйте в конструкторе класса (authors = new HashSet<>();), чтобы избежать NullPointerException.
Проверка возвращаемого значения: Используйте boolean от add/remove для логики (например, уведомление о дубликате).
Custom уникальность: Если уникальность по полю (как author), убедитесь, что equals/hashCode в Book учитывают только author, если нужно (но для Set это не требуется, так как String имеет правильные методы).
Расширение проекта: Подумайте, как добавить метод для проверки, существует ли автор перед добавлением книги (используйте contains).
Производительность: Для малого количества авторов (сотни) любая реализация подойдет; для больших — HashSet fastest.
Практическое задание
Задача 1: Добавьте в Library метод isAuthorUnique(String authorName), который использует contains для проверки, есть ли автор в Set.
Задача 2: В addBook перед добавлением автора проверьте с помощью contains, и если он новый, выведите сообщение "Новый автор добавлен".
Задача 3: Создайте 5-6 книг с 3-4 уникальными авторами (некоторые повторяются), добавьте их, выведите авторов и убедитесь в уникальности.
Реализуйте эти задачи самостоятельно, следуя шагам урока. Это закрепит работу с Set в контексте проекта.
#Java #для_новичков #beginner #Collections #Set
После реализации протестируйте, чтобы убедиться в правильной работе уникальности.
Запустите проект:
Правой кнопкой на Main.java → Run 'Main.main()'.
В консоли увидите вывод уникальных авторов. Убедитесь, что дубликаты авторов не появляются в списке.
Проверьте уникальность:
Добавьте две книги с одним автором — в Set должно быть только одно имя.
Попробуйте добавить null как автора (если поле author позволяет) — проверьте поведение Set (HashSet позволит один null).
Отладка:
Установите breakpoint в методе addBook перед authors.add() и после — шагайте (F8) и смотрите, меняется ли размер Set.
Если ошибки: NullPointerException (если Set не инициализировано), ArrayIndexOutOfBoundsException (если массив переполнен) — добавьте проверку на размер.
В консоли выводите сообщения, например, если add вернул false: "Автор [name] уже существует".
Эксперименты:
Измените реализацию Set на LinkedHashSet — проверьте, сохраняется ли порядок добавления авторов.
Попробуйте TreeSet — добавьте Comparator, если нужно сортировать авторов по алфавиту (TreeSet требует Comparable для элементов).
Полезные советы для новичков
Инициализация Set: Всегда инициализируйте в конструкторе класса (authors = new HashSet<>();), чтобы избежать NullPointerException.
Проверка возвращаемого значения: Используйте boolean от add/remove для логики (например, уведомление о дубликате).
Custom уникальность: Если уникальность по полю (как author), убедитесь, что equals/hashCode в Book учитывают только author, если нужно (но для Set это не требуется, так как String имеет правильные методы).
Расширение проекта: Подумайте, как добавить метод для проверки, существует ли автор перед добавлением книги (используйте contains).
Производительность: Для малого количества авторов (сотни) любая реализация подойдет; для больших — HashSet fastest.
Практическое задание
Задача 1: Добавьте в Library метод isAuthorUnique(String authorName), который использует contains для проверки, есть ли автор в Set.
Задача 2: В addBook перед добавлением автора проверьте с помощью contains, и если он новый, выведите сообщение "Новый автор добавлен".
Задача 3: Создайте 5-6 книг с 3-4 уникальными авторами (некоторые повторяются), добавьте их, выведите авторов и убедитесь в уникальности.
Реализуйте эти задачи самостоятельно, следуя шагам урока. Это закрепит работу с Set в контексте проекта.
#Java #для_новичков #beginner #Collections #Set
👍1
Что выведет код?
#Tasks
import java.util.*;
public class Task151025 {
public static void main(String[] args) {
Set<List<Integer>> set = new HashSet<>();
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(1, 2, 3);
set.add(list1);
set.add(list2);
list1.add(4);
System.out.println(set.size());
System.out.println(set.contains(list1));
System.out.println(set.contains(list2));
}
}
#Tasks
Варианты ответа:
Anonymous Quiz
18%
2, false, false
9%
2, false, true
27%
2, true, false
45%
Ошибка выполнения
👍4
Вопрос с собеседований
Что такое CountDownLatch?🤓
Ответ:
CountDownLatch — это синхронизатор, который блокирует выполнение потоков до тех пор, пока счётчик не станет 0.
Потоки вызывают countDown(), уменьшая счётчик, а другие ждут через await().
Используется для ожидания завершения задач.
#собеседование
Что такое CountDownLatch?
Ответ:
CountDownLatch
Потоки вызывают countDown(), уменьшая счётчик, а другие ждут через await().
Используется для ожидания завершения задач.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2