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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Коллекции в Java

Глава 1. Введение в коллекции

Основные характеристики коллекций: время доступа (Big O), хранение уникальных элементов, упорядоченность и сортировка

Big O (или O-нотация) — это математическая нотация, которая описывает, как растет время выполнения операции (или использование памяти) в зависимости от размера данных (n — количество элементов). Она оценивает "наихудший случай" и помогает сравнивать эффективность коллекций.

Основные обозначения Big O:
- O(1): Постоянное время — операция не зависит от размера (например, доступ по индексу в массиве).
- O(log n): Логарифмическое время — быстро растет, но эффективно (например, поиск в отсортированном дереве).
- O(n): Линейное время — пропорционально размеру (например, перебор списка).
- O(n log n): Для сортировки (например, TreeSet).
- O(n²): Квадратичное — медленно для больших n (избегайте).


Для коллекций Big O применяется к основным операциям: добавление (add), удаление (remove), поиск (contains/get), вставка.

Почему важно: Выбор коллекции влияет на производительность. Для миллионов элементов O(1) лучше O(n).


Хранение уникальных элементов

Коллекции различаются по тому, позволяют ли они дубликаты элементов.


Коллекции с уникальными элементами:
- Интерфейс Set<E>: Не позволяет дубликаты. Если добавить существующий элемент, он игнорируется (add() возвращает false).
- Пример: HashSet, TreeSet, LinkedHashSet.
- Нюанс: Уникальность определяется методом equals() и hashCode() (для HashSet). Переопределите их для custom классов.


Коллекции с дубликатами:
- Интерфейс List<E>: Позволяет дубликаты и хранит их в порядке вставки.
- Пример: ArrayList, LinkedList.
- Queue<E> и Deque<E>: Могут позволять дубликаты, в зависимости от реализации.


- Map<K, V>: Ключи уникальны (как Set), значения могут дублироваться.

Пример кода для уникальности:
import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) {
// Set: Уникальные элементы
Set<String> uniqueNames = new HashSet<>();
uniqueNames.add("Алексей");
uniqueNames.add("Алексей"); // Игнорируется
System.out.println(uniqueNames.size()); // 1

// List: Дубликаты разрешены
List<String> names = new ArrayList<>();
names.add("Алексей");
names.add("Алексей");
System.out.println(names.size()); // 2
}
}


- Нюанс: Для custom объектов в Set переопределите equals() и hashCode(), иначе дубликаты возможны (сравнение по ссылке).


#Java #для_новичков #beginner #Collections #BigO
👍4
Упорядоченность элементов

Упорядоченность — это сохранение порядка элементов (по вставке или сортировке).

Коллекции с порядком вставки:
- List<E>: Всегда упорядочены по индексу (порядок добавления).
- Пример: ArrayList, LinkedList.
- LinkedHashSet<E>: Set с порядком вставки.
- LinkedHashMap<K, V>: Map с порядком вставки.

Коллекции без порядка:
- HashSet<E>: Не гарантирует порядок (зависит от хэша).
- HashMap<K, V>: Не упорядочен.


Отсортированные коллекции: Подробнее в разделе о сортировке.

Пример:
import java.util.HashSet;
import java.util.LinkedHashSet;

public class Main {
public static void main(String[] args) {
// HashSet: Без порядка
Set<String> hashSet = new HashSet<>();
hashSet.add("Яблоко");
hashSet.add("Банан");
hashSet.add("Апельсин");
System.out.println(hashSet); // Может быть [Банан, Яблоко, Апельсин] — непредсказуемо

// LinkedHashSet: Порядок вставки
Set<String> linkedSet = new LinkedHashSet<>();
linkedSet.add("Яблоко");
linkedSet.add("Банан");
linkedSet.add("Апельсин");
System.out.println(linkedSet); // [Яблоко, Банан, Апельсин] — сохраняет порядок
}
}


- Нюанс: Порядок в HashSet может меняться при ресайзе (rehashing), так что не полагайтесь на него.


Сортировка элементов

Сортировка — это автоматическое упорядочивание элементов по какому-то критерию (натуральный порядок или Comparator).

Отсортированные коллекции:
- SortedSet<E> (подинтерфейс Set): Уникальные, отсортированные элементы.
- Реализация: TreeSet<E> — использует красно-черное дерево.
- SortedMap<K, V> (подинтерфейс Map): Отсортированные ключи.
- Реализация: TreeMap<K, V>.


Как работает сортировка:
- Элементы должны быть Comparable<E> (метод compareTo()) для натурального порядка (числа по возрастанию, строки по алфавиту).
- Или используйте Comparator при создании: new TreeSet<>(comparator).
- Нюанс: Добавление/поиск — O(log n), так как дерево балансировано.


Пример 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);
System.out.println(numbers); // [1, 3, 5] — отсортировано

// Custom 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]
}
}


- Нюанс: TreeSet не позволяет null (NullPointerException), так как сравнивает элементы.
Для сортировки существующих коллекций используйте Collections.sort(List list) или List.sort(Comparator).



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

- Big O в практике: Для малого n (сотни элементов) разница мала, но для миллионов — критична (выберите HashSet для быстрого contains).
- Уникальность: Set для словарей, List для списков с повторами.
- Упорядоченность: Linked* для сохранения вставки, Tree* для автосортировки.
- Сортировка: TreeSet/Map для постоянной сортировки; Collections.sort() для разовой.
- Ошибки: Null в TreeSet — NPE; дубли в Set — игнор.
- Ресурсы: Java API docs для java.util.



#Java #для_новичков #beginner #Collections #BigO
👍4
Раздел 6. Коллекции в Java

Глава 1. Введение в коллекции

(Практика):
Начать проект «Библиотека».
Создать класс Book с полями title, author, year.
Сделать список книг (пока как массив) и вывести их на экран


Перед тем, как писать код, важно правильно настроить среду разработки. Это обеспечит удобную работу и избежание ошибок на старте.

Запустите IntelliJ IDEA:
Если IDE не открыта, запустите её. Убедитесь, что у вас установлен JDK. Если проект новый, выберите "New Project" на приветственном экране.

Создайте новый проект:
В окне создания проекта выберите "Java" как тип.
Укажите имя проекта, например, "LibraryProject".
Выберите JDK в поле Project SDK (если не настроено, добавьте путь к JDK).
Оставьте остальные настройки по умолчанию (без Maven или Gradle для простоты) и нажмите "Create".
IDE создаст структуру проекта с папкой src для исходного кода.

Настройте структуру проекта:
В дереве проекта (слева) найдите src.
Если нужно, создайте пакет для организации кода: Правой кнопкой на src → New → Package → Назовите "library" (или другое имя). Это хорошая практика для группировки классов.

Создание класса Book
Теперь создадим основной класс для представления книги. Это будет простой класс с полями, который позже расширим.

Создайте класс Book:
В пакете (или прямо в src, если без пакета) щелкните правой кнопкой → New → Java Class.
Назовите класс "Book".
IDE создаст файл
Book.java с базовой структурой

public class Book {}


Добавьте поля:
В теле класса объявите три приватных поля:
title типа String (для названия книги).
author типа String (для автора).
year типа int (для года издания).


Используйте модификатор private для инкапсуляции, как мы изучали в ООП.


Добавьте конструктор:
Создайте публичный конструктор, который принимает три параметра (String title, String author, int year) и присваивает их соответствующим полям с помощью this.
Это позволит создавать объекты Book с начальными значениями.

Добавьте метод для вывода:
Создайте публичный метод, например, printDetails(), который выводит информацию о книге на экран с помощью System.out.println.
В нём используйте поля для формирования строки вроде "Название: [title], Автор: [author], Год: [year]".



Создание списка книг с использованием массива


Пока мы используем массив как простую структуру для хранения списка книг — это поможет сравнить с коллекциями позже.

Создайте класс Main:
Аналогично создайте новый класс "Main" в том же пакете.
Добавьте статический метод main(String[] args) — точку входа.


Объявите массив:
В методе main объявите массив объектов Book фиксированного размера, например, Book[] books = new Book[3]; (размер выберите небольшой для теста).

Инициализируйте массив:
Создайте несколько объектов Book с помощью new Book(title, author, year) и присвойте их элементам массива (books[0] = new Book(...); и т.д.).
Используйте разные значения для демонстрации (например, книги разных авторов и годов).


Выведите список на экран:
Используйте цикл for (или for-each: for (Book book : books)) для перебора массива.
В цикле вызовите метод printDetails() для каждого элемента, чтобы вывести информацию о книгах.


#Java #для_новичков #beginner #Collections #Практика
👍3🔥1
Тестирование и отладка проекта

После реализации протестируйте проект, чтобы убедиться, что всё работает.

Запустите проект:
Правой кнопкой на файле Main.java → Run 'Main.main()'.
В консоли IDE вы должны увидеть вывод списка книг с их деталями.


Отладка:
Если ошибки: Проверьте синтаксис (точки с запятой, скобки).
Используйте отладчик: Установите breakpoint (красная точка слева от строки в main), запустите в debug-режиме (Shift+F9) и шагайте по коду (F8).
Общие проблемы: NullPointerException (если массив не инициализирован), IndexOutOfBoundsException (если выход за пределы массива).


Проверьте вывод:
Убедитесь, что книги выводятся в порядке добавления в массив.
Попробуйте изменить размер массива или добавить больше книг — увидите, как фиксированный размер ограничивает (это мотивирует к коллекциям позже).



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

Организация кода: Используйте пакеты для группировки (например, library.models для Book).
Инкапсуляция: Даже в простом проекте делайте поля private и добавьте геттеры/сеттеры, если нужно изменять.
Массивы vs коллекции: Заметьте ограничения массива (фиксированный размер, ручное управление) — в следующих уроках заменим на ArrayList.
Комментарии: Добавляйте // комментарии к шагам, чтобы код был читаемым.
Версионирование: Если используете Git, создайте репозиторий и закоммитьте начальную версию проекта.
Ресурсы: Документация Oracle по классам и массивам для напоминания синтаксиса.



Практическое задание

Задача 1: Расширьте класс Book, добавив приватное поле isbn (String) и обновите конструктор и метод printDetails() для его включения.
Задача 2: Увеличьте массив до 5 элементов, добавьте больше книг и убедитесь, что вывод работает.
Задача 3: Попробуйте вывести только книги после определенного года — используйте if в цикле перебора массива.

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


#Java #для_новичков #beginner #Collections #Практика
👍4🔥1
Коллекции в 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
Коллекции в 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
👍3
Коллекции в 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():
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():
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
Раздел 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
👍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
👍1