Java for Beginner
745 subscribers
714 photos
201 videos
12 files
1.16K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
🗓 История IT-технологий сегодня — 07 октября


ℹ️ Кто родился в этот день

Джон Эдвард Хопкрофт (родился 7 октября 1939 года) — американский теоретик компьютерных наук, лауреат премии Тьюринга 1986 за фундаментальные достижения в алгоритмах и структурах данных.

Ви́ктор Леони́дович Матро́сов (7 октября 1950, Москва — 19 января 2015, Московская область) — советский / российский математик; профессор, доктор физико-математических наук.


🌐 Знаковые события

1959 — космический аппарат «Луна-3» впервые совершил облёт Луны. Аппарат сделал первые фотоснимки её обратной стороны и передал изображения на Землю.


#Biography #Birth_Date #Events #07Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Коллекции в Java

Глава 3. Set — множества

Интерфейс Set. Особенности множеств


Интерфейс Set<E> — это часть Java Collections Framework (JCF), который представляет коллекцию уникальных элементов без дубликатов. Set является подинтерфейсом Collection, но с ключевым отличием: он не позволяет хранить одинаковые элементы. Если вы пытаетесь добавить дубликат, операция игнорируется.

Основные характеристики Set:
Уникальность элементов: Да, дубликаты не хранятся.
Упорядоченность: В общем случае нет (зависит от реализации).
Сортировка: Нет по умолчанию, но возможна в подтипах.
Время доступа (Big O): Для основных операций (add, remove, contains) — O(1) в HashSet, O(log n) в TreeSet.


Set моделирует математическое множество: элементы уникальны, нет индексации, фокус на наличии/отсутствии.

Методы Set (наследуются от Collection, но с нюансами):
boolean add(E e): Добавляет элемент, если его нет (возвращает true, если добавлен).
boolean remove(Object o): Удаляет элемент, если он есть.
boolean contains(Object o): Проверяет наличие.
int size(): Размер.
boolean isEmpty(): Пустота.
Iterator<E> iterator(): Для перебора (нет порядка по умолчанию).
void clear(): Очистка.

Нюанс: Set не имеет get(int index) — нет индексации, как в List. Перебор через Iterator или for-each.


Особенности множеств в Java

Множества в Java имеют несколько важных особенностей, которые определяют их использование:

Уникальность элементов:
Set автоматически предотвращает дубликаты на основе методов equals() и hashCode() (для HashSet) или compareTo() (для TreeSet).
Если добавить существующий элемент, add() возвращает false, коллекция не меняется.
Нюанс: Для custom классов обязательно переопределите equals() и hashCode() (используйте Objects.equals() и Objects.hash()). Без этого уникальность по ссылке, не по значению.


Отсутствие гарантированного порядка:
В HashSet порядок непредсказуем (зависит от хэша).
В LinkedHashSet — порядок вставки.
В TreeSet — сортированный порядок.
Нюанс: Не полагайтесь на порядок в HashSet — он может измениться при ресайзе.


Null элементы:
HashSet и LinkedHashSet позволяют один null.
TreeSet — нет (NullPointerException, так как сравнивает).
Нюанс: Null в Set — редко рекомендуется, но возможно.


Итерация и модификация:
Перебор через for-each или Iterator.
Нюанс: Во время итерации нельзя модифицировать Set (ConcurrentModificationException). Используйте Iterator.remove() для удаления.


Производительность:

HashSet: O(1) для add/remove/contains (средний случай).
TreeSet: O(log n), но с автосортировкой.
Нюанс: HashSet требует хорошего hashCode() — плохой приводит к O(n) worst-case.


Синхронизация:
Стандартные реализации не thread-safe. Для многопоточности: Collections.synchronizedSet(Set set) или ConcurrentHashSet (из Guava).


#Java #для_новичков #beginner #Collections #Set
👍6
Примеры использования Set

HashSet: Для быстрых операций без порядка.
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("Банан");
fruits.add("Яблоко"); // Игнорируется

System.out.println(fruits.size()); // 2
System.out.println(fruits.contains("Банан")); // true

for (String fruit : fruits) {
System.out.println(fruit); // Порядок непредсказуем
}
}
}


Вывод: Размер 2, содержит "Банан", элементы в случайном порядке.


LinkedHashSet: С сохранением порядка вставки.
import java.util.LinkedHashSet;
import java.util.Set;

public class Main {
public static void main(String[] args) {
Set<String> fruits = new LinkedHashSet<>();
fruits.add("Яблоко");
fruits.add("Банан");
fruits.add("Апельсин");

for (String fruit : fruits) {
System.out.println(fruit); // Яблоко, Банан, Апельсин — порядок вставки
}
}
}



TreeSet: С автосортировкой.

import java.util.TreeSet;
import java.util.Set;

public class Main {
public static void main(String[] args) {
Set<Integer> numbers = new TreeSet<>();
numbers.add(5);
numbers.add(1);
numbers.add(3);

for (Integer num : numbers) {
System.out.println(num); // 1, 3, 5 — отсортировано
}
}
}


Нюанс: Для custom классов в TreeSet реализуйте Comparable или используйте Comparator при создании.


Как создать и использовать Set в IntelliJ IDEA

Импорт: В коде напишите Set — IDE предложит import java.util.Set; и реализацию (HashSet и т.д.).
Generics: Используйте Set для типобезопасности.
Автодополнение: При add() IDE подскажет параметры.
Отладка: В debug смотрите содержимое Set — IDE покажет элементы.
Конвертация: Из List в Set: new HashSet<>(list) — для удаления дубликатов.



Полезные советы для новичков

Выбор реализации: HashSet для скорости, LinkedHashSet для порядка, TreeSet для сортировки.
equals() и hashCode(): Всегда переопределяйте в custom классах для Set/Map (используйте
@Override и Objects.hash()).
Удаление дубликатов: Set — быстрый способ: new HashSet<>(list).
Null: Избегайте в TreeSet; в HashSet — осторожно.
Итерация: For-each безопасен для чтения, но не модифицируйте во время перебора.


#Java #для_новичков #beginner #Collections #Set
👍4
Что выведет код?

import java.util.*;

public class Task071025 {
public static void main(String[] args) {
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 2, 1));

System.out.println(set1.hashCode() == set2.hashCode());
System.out.println(set1.toString().equals(set2.toString()));
}
}


#Tasks
👍1
Варианты ответа:
Anonymous Quiz
32%
true true
27%
true false
27%
false true
14%
false false
👍1
Вопрос с собеседований

Можно ли поймать Error?🤓

Ответ:

Технически Error можно поймать через catch, но этого не делают.

Errors сигнализируют о критических проблемах JVM (например, OutOfMemoryError, StackOverflowError), которые исправить на уровне приложения невозможно.

Их обработка только маскирует проблему.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🗓 История IT-технологий сегодня — 08 октября


ℹ️ Кто родился в этот день

Хендрик Якоб (Яап) ван ден Херик (родился 8 октября 1947 года в Роттердаме) — нидерландский компьютерный учёный, профессор Университета Лейдена; известен работами по компьютерным шахматам и искусственному интеллекту.

Роберт Бертран Франс (8 октября 1960 г. – 15 февраля 2015 г.) — родом из Ямайки, американский учёный в области формальных методов, Unified Modeling Language (UML) и модельно-ориентированного развития ПО.


🌐 Знаковые события

1978 — ядерный взрыв «Вятка» (15 килотонн).


#Biography #Birth_Date #Events #08Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Реактивное программирование

Комбинации потоков в Reactor: concat, merge и другие

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


Concat: последовательное объединение потоков


Concat — оператор для слияния потоков по очереди: сначала все элементы первого, потом второго и так далее. Он ждёт завершения предыдущего (onComplete), прежде чем перейти к следующему. Идеален, когда порядок важен и параллелизм не нужен: например, загрузка данных по шагам.


Пример на Flux:
import reactor.core.publisher.Flux;
import java.time.Duration;
Flux<String> first = Flux.just("Шаг 1a", "Шаг 1b").delayElements(Duration.ofSeconds(1)); // Задержка для симуляции
Flux<String> second = Flux.just("Шаг 2a", "Шаг 2b");
Flux<String> combined = Flux.concat(first, second);

combined.subscribe(System.out::println); // Вывод: "Шаг 1a" (через 1с), "Шаг 1b" (ещё 1с), "Шаг 2a", "Шаг 2b"

Здесь concat гарантирует последовательность: второй Flux стартует только после onComplete первого. Если ошибка в первом — весь поток прервётся onError.


На Mono:
Mono<String> m1 = Mono.just("A").delayElement(Duration.ofSeconds(1));
Mono<String> m2 = Mono.just("B");
Flux<String> seq = Flux.concat(m1, m2); // Mono как Flux с одним элементом


Почему concat полезен? В традиционных подходах (thenCompose в CompletableFuture) вы пишете цепочки вручную, рискуя callback-адом. Здесь — декларативно, с автоматическим backpressure: запросы идут к текущему потоку. Минус: медленный, если источники асинхронные — ждёт завершения.
Вариант: concatWith(other) на одном Flux для добавления.



Merge: параллельное слияние по готовности


Merge — для объединения потоков параллельно: элементы выдаются по мере готовности, без ожидания завершения. Порядок не гарантирован — зависит от скорости источников. Идеален для независимых событий: например, слияние логов из сервисов.

Пример:

Flux<String> slow = Flux.just("Медленный 1", "Медленный 2").delayElements(Duration.ofSeconds(2));
Flux<String> fast = Flux.just("Быстрый A", "Быстрый B").delayElements(Duration.ofMillis(500));
Flux<String> merged = Flux.merge(slow, fast);

merged.subscribe(System.out::println); // Возможный вывод: "Быстрый A" (0.5с), "Быстрый B" (ещё 0.5с), "Медленный 1" (2с), "Медленный 2" (ещё 2с)

Здесь merge отдает элементы, как только они готовы — параллельно. Если ошибка в одном — весь поток onError (по умолчанию), но можно настроить.


На Mono: merge работает с Mono как с Flux'ом одного элемента.

Почему merge лучше потоков? В старых моделях (join в Executor) вы ждёте всех, блокируя. Здесь — асинхронно, с backpressure: merge распределяет запросы по источникам пропорционально. Параметр: merge(func, concurrency) для ограничения параллелизма.
Вариант: mergeWith(other) на одном Flux.



#Java #middle #Reactor #Concat #Merge #Zip #CombineLatest
👍2
Zip: попарная комбинация элементов

Zip — объединяет элементы из потоков попарно: берёт первый от первого, первый от второго и т.д., применяя функцию для слияния. Завершается, когда любой поток исчерпан. Идеален для синхронизации: например, zip координат X и Y в точки.

Пример:
Flux<Integer> xCoords = Flux.just(1, 2, 3);
Flux<Integer> yCoords = Flux.just(10, 20, 30, 40); // Лишний элемент игнорируется
Flux<String> points = Flux.zip(xCoords, yCoords, (x, y) -> "(" + x + ", " + y + ")");

points.subscribe(System.out::println); // Вывод: "(1, 10)", "(2, 20)", "(3, 30)"

Здесь zip ждёт пару: если один медленный — задерживает. Для >2 потоков: zip(tuple -> ..., flux1, flux2, flux3).


Почему zip решает проблемы? Вместо ручных семафоров или ожиданий в циклах, декларативно комбинируете асинхронные источники. Backpressure: запрашивает у всех равномерно.

CombineLatest: комбинация последних элементов


CombineLatest — выдаёт комбинацию последних элементов от каждого потока, как только любой обновляется. Не ждёт пар — всегда использует свежие. Идеален для реального времени: например, комбинация курсов валют.


Пример:
Flux<String> stockA = Flux.just("A:100", "A:110").delayElements(Duration.ofSeconds(1));
Flux<String> stockB = Flux.just("B:200").delayElements(Duration.ofSeconds(2));
Flux<String> latest = Flux.combineLatest(stockA, stockB, (a, b) -> a + " + " + b);

latest.subscribe(System.out::println); // Вывод примерно: "A:100 + B:200" (после 2с), "A:110 + B:200" (ещё 1с после)

Здесь combineLatest реагирует на изменения: при обновлении A использует последний B. Для >2: combineLatest(tuple -> ..., fluxes).


В отличие от zip (строгие пары), здесь — динамика. Backpressure: как в merge.


Другие комбинации: withLatestFrom и concatMap

WithLatestFrom: похож на combineLatest, но "master"-поток (основной) триггерит выдачу, беря последние из второстепенных. Пример: flux.withLatestFrom(other, (main, other) -> main + other).
ConcatMap: как flatMap, но последовательный (как concat внутри). Для orderly асинхронных подпотоков.

Эти дополняют: выбирайте по сценарию — последовательность (concat/concatMap), параллелизм (merge/flatMap) или синхронизация (zip/combineLatest).



Практические советы и подводные камни

Ошибки: по умолчанию onError останавливает всё — используйте onErrorResume для продолжения.
Параллелизм: в merge/flatMap устанавливайте prefetch (буфер) или concurrency для тюнинга.
Камень: бесконечные потоки в merge — рискуете OOM; добавьте take() или limitRate().
Тестирование: StepVerifier.create(Flux.merge(f1, f2)).expectNextMatches(...).verify();



#Java #middle #Reactor #Concat #Merge #Zip #CombineLatest
👍3
Что выведет код?

public class Task081025 {
public static void main(String[] args) {
try {
System.out.print("A");
throw new RuntimeException();
} catch (RuntimeException e) {
System.out.print("B");
throw new NullPointerException();
} finally {
System.out.print("C");
throw new IllegalArgumentException();
}
}
}


#Tasks
👍2
Вопрос с собеседований

Что лучше: throw или return кода ошибки?🤓

Ответ:

В Java принято использовать исключения (throw), а не коды ошибок.

Исключения позволяют разделить бизнес-логику и обработку ошибок, делать код чище и поддерживаемее.

Коды ошибок уместны в низкоуровневых системах, но не в Java-приложениях.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🗓 История IT-технологий сегодня — 09 октября


ℹ️ Кто родился в этот день

Джон Бёрдетт Гейдж (родился 9 октября 1942 года) — американский компьютерный учёный и технологический менеджер, один из ранних сотрудников Sun Microsystems, автор фразы «The Network is the Computer», занимал должность вице-президента по науке в Sun; ключевая фигура в развитии корпоративных ИТ-инфраструктур.

Джером Говард «Джерри» Солцер (родился 9 октября 1939 года) — американский специалист по компьютерным системам; участвовал в проектах Multics, Project Athena, известен влиянием на архитектуру систем безопасности и лицензии ПО.


🌐 Знаковые события

1604 — первые наблюдения европейцами сверхновой звезды SN 1604 или Сверхновая Кеплера, вспыхнувшей в нашей Галактике в созвездии Змееносца.


#Biography #Birth_Date #Events #09Октября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Коллекции в Java

Глава 3. Set — множества

Реализации: HashSet, LinkedHashSet, TreeSet.

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


Интерфейс Set<E> имеет несколько реализаций в JCF, каждая оптимизирована под разные сценарии. Все они обеспечивают уникальность элементов, но отличаются по порядку, сортировке и времени операций.


HashSet<E>

Описание: HashSet — самая распространенная реализация Set, основанная на хэш-таблице (HashMap внутри). Она хранит элементы в "корзинах" (buckets) на основе их хэш-кода, что обеспечивает быстрый поиск и добавление.

Особенности:
Уникальность: Да, дубликаты игнорируются.
Порядок: Нет гарантированного порядка (зависит от хэша, может меняться при ресайзе).
Сортировка: Нет.
Null: Разрешен один null.
Big O: Средний случай — O(1) для add, remove, contains (константное время). Worst-case — O(n) при коллизиях хэшей, но редко с хорошим hashCode().


Внутренняя работа: Элементы хранятся как ключи в HashMap (значения — dummy объект). Хэш-код определяет бакет, equals() — проверку уникальности.

Нюансы:
Зависит от hashCode() и equals(): Плохо реализованные методы приводят к коллизиям и снижению производительности.
Ресайз: При заполнении >75% (load factor) таблица удваивается, что может занять O(n) времени.
Thread-safety: Не безопасен для многопоточности — используйте Collections.synchronizedSet(new HashSet<>()).
Память: Занимает больше, чем ArrayList, из-за хэш-таблицы.


Пример кода:
javaimport 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("Банан");
fruits.add("Яблоко"); // Игнорируется

System.out.println(fruits.contains("Банан")); // true
fruits.remove("Яблоко");

for (String fruit : fruits) {
System.out.println(fruit); // Порядок непредсказуем, например: Банан
}
}
}

Вывод: contains вернет true, размер 1 после удаления, порядок случайный.


LinkedHashSet<E>

Расширение HashSet с двусвязным списком для сохранения порядка вставки. Внутри — HashMap с LinkedHashMap-логикой.

Особенности:
Уникальность: Да.
Порядок: Сохраняет порядок вставки (insertion order).
Сортировка: Нет.
Null: Разрешен один null.
Big O: O(1) для add/remove/contains (как HashSet), но с overhead на ссылки списка.


Внутренняя работа: Каждый элемент имеет ссылки prev/next для списка, плюс хэш-таблица для уникальности.

Нюансы:
Больше памяти, чем HashSet (из-за ссылок).
Итерация: O(n), но предсказуема по порядку вставки.
Полезен для кэшей с LRU (least recently used), но для простого порядка — эффективен.
Thread-safety: Нет, как у HashSet.


Пример кода:
javaimport java.util.LinkedHashSet;
import java.util.Set;

public class Main {
public static void main(String[] args) {
Set<String> fruits = new LinkedHashSet<>();
fruits.add("Яблоко");
fruits.add("Банан");
fruits.add("Апельсин");

for (String fruit : fruits) {
System.out.println(fruit); // Яблоко, Банан, Апельсин — порядок вставки
}
}
}

Вывод: Элементы в том порядке, в котором добавлены.



#Java #для_новичков #beginner #Collections #HashSet #LinkedHashSet #TreeSet
👍3
TreeSet<E>

Реализация SortedSet<E>, основанная на красно-черном дереве. Автоматически сортирует элементы.

Особенности:
Уникальность: Да.
Порядок: Нет (игнорирует порядок вставки), но отсортирован по натуральному порядку или Comparator.
Сортировка: Да, всегда отсортирован.
Null: Не разрешен (NullPointerException при сравнении).
Big O: O(log n) для add/remove/contains (дерево балансировано).


Внутренняя работа: Элементы хранятся в узлах дерева, сравниваются через Comparable.compareTo() или Comparator.


Нюансы:

Элементы должны реализовывать Comparable<E> или предоставить Comparator при создании: new TreeSet<>(comparator).
Для custom классов: Реализуйте Comparable или Comparator, иначе ClassCastException.
Итерация: O(n), в отсортированном порядке.
Дополнительные методы: first(), last(), headSet(E to), tailSet(E from) — для подмножеств.
Thread-safety: Нет, используйте Collections.synchronizedSortedSet(new TreeSet<>()).
Память: Больше, чем HashSet, из-за структуры дерева.


Пример кода:
javaimport java.util.TreeSet;
import java.util.Set;

public class Main {
public static void main(String[] args) {
Set<Integer> numbers = new TreeSet<>();
numbers.add(5);
numbers.add(1);
numbers.add(3);

for (Integer num : numbers) {
System.out.println(num); //отсортировано
}

// С Comparator для обратного порядка
Set<Integer> reverseNumbers = new TreeSet<>((a, b) -> b - a);
reverseNumbers.add(5);
reverseNumbers.add(1);
reverseNumbers.add(3);
System.out.println(reverseNumbers); // [5, 3, 1]
}
}

Вывод: Элементы всегда отсортированы.



Применение множеств: Удаление дубликатов и проверка уникальности


Множества идеальны для задач, где нужна уникальность без дубликатов.

Удаление дубликатов:
Преобразуйте List или массив в Set — дубликаты автоматически удалятся.
Нюанс: Порядок может потеряться (используйте LinkedHashSet для сохранения).


Пример кода:
javaimport java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;

public class Main {
public static void main(String[] args) {
List<String> duplicates = new ArrayList<>();
duplicates.add("Яблоко");
duplicates.add("Банан");
duplicates.add("Яблоко");

Set<String> unique = new HashSet<>(duplicates);
System.out.println(unique); // [Банан, Яблоко]

// С сохранением порядка
Set<String> orderedUnique = new LinkedHashSet<>(duplicates);
System.out.println(orderedUnique); // [Яблоко, Банан]
}
}

Вывод: Уникальные элементы, без дубликатов.


Проверка уникальности:
Используйте contains() для быстрой проверки наличия (O(1) в HashSet).
Или add() — если false, элемент уже есть.
Нюанс: Для больших данных Set эффективнее, чем перебор List (O(n)).


Пример кода:
javaimport java.util.HashSet;
import java.util.Set;

public class Main {
public static void main(String[] args) {
Set<String> users = new HashSet<>();
users.add("user1");

if (users.contains("user2")) {
System.out.println("Пользователь существует");
} else {
users.add("user2");
System.out.println("Новый пользователь добавлен");
}

if (!users.add("user1")) {
System.out.println("Дубликат не добавлен"); // add возвращает false
}
}
}

Вывод: Проверка и добавление без дубликатов.



Полезные советы для новичков

HashSet по умолчанию: Для большинства случаев уникальности.
Custom классы: Всегда реализуйте equals() и hashCode() (используйте IDE: Generate → equals() and hashCode()).
Comparator в TreeSet: Для custom сортировки: new TreeSet<>((a, b) -> a.compareTo(b)).
Удаление дубликатов: Удобно для списков из файлов или БД.
Память: TreeSet дороже по памяти, HashSet — оптимален.
Ошибки: ClassCastException в TreeSet без Comparable; ConcurrentModificationException при модификации во время итерации (используйте Iterator.remove()).



#Java #для_новичков #beginner #Collections #HashSet #LinkedHashSet #TreeSet
👍2
Что выведет код?

import java.util.LinkedHashSet;

public class Task091025 {
public static void main(String[] args) {
LinkedHashSet<Integer> set = new LinkedHashSet<>();

set.add(1);
set.add(2);
set.add(3);
set.remove(2);
set.add(2);

System.out.println(set);
}
}


#Tasks
👍1
Варианты ответа:
Anonymous Quiz
12%
[1, 2, 3]
0%
[2, 1, 3]
82%
[1, 3, 2]
6%
[1, 3]
👍1
Вопрос с собеседований

Что такое fail-fast и fail-safe итераторы?🤓

Ответ:

Fail-fast
итераторы (например, у ArrayList, HashMap) выбрасывают ConcurrentModificationException, если коллекция изменилась во время обхода.


Fail-safe (например, у CopyOnWriteArrayList) работают с копией коллекции и не падают, но дороже по памяти.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2