Ответ
Set в Java — это коллекция (java.util.Set), которая не допускает дубликатов элементов. Его основная контрактная обязанность — гарантировать уникальность, что часто реализуется через методы equals() и hashCode() объектов.
Ключевые характеристики:
- Уникальность: Не может содержать двух элементов
e1иe2таких, чтоe1.equals(e2) == true. Добавление дубликата просто игнорируется (методadd()возвращаетfalse). - Порядок: Не гарантирует никакого порядка элементов, если только не используется конкретная реализация, которая его обеспечивает (например,
LinkedHashSet). - Один
null: Большинство реализаций допускают не более одного элементаnull.
Основные реализации и их отличия:
| Реализация | Внутренняя структура | Порядок | Время выполнения (Big O) | Особенности |
|---|---|---|---|---|
HashSet |
Хэш-таблица | Не гарантирован | add(), remove(), contains(): O(1) в среднем |
Самая распространенная, требует корректных hashCode() и equals(). |
LinkedHashSet |
Хэш-таблица + связный список | Порядок вставки (insertion-order) | Немного медленнее HashSet, но тоже O(1) |
Полезен, когда нужна уникальность + предсказуемый порядок итерации. |
TreeSet |
Красно-черное дерево | Натуральный порядок или порядок заданный Comparator |
add(), remove(), contains(): O(log n) |
Элементы отсортированы. Реализует интерфейс SortedSet/NavigableSet. |
Примеры использования:
import java.util.*;
public class SetExample {
public static void main(String[] args) {
// 1. HashSet - для быстрой проверки принадлежности
Set<String> uniqueWords = new HashSet<>();
uniqueWords.add("apple");
uniqueWords.add("banana");
boolean added = uniqueWords.add("apple"); // false, дубликат не добавлен
System.out.println(uniqueWords); // [banana, apple] (порядок может быть любым)
System.out.println("Contains 'apple': " + uniqueWords.contains("apple")); // true
// 2. LinkedHashSet - сохраняем порядок добавления (например, для истории уникальных посещений)
Set<Integer> visitOrder = new LinkedHashSet<>();
visitOrder.add(100);
visitOrder.add(200);
visitOrder.add(100); // Игнорируется
visitOrder.add(300);
System.out.println("Visit order: " + visitOrder); // [100, 200, 300]
// 3. TreeSet - автоматическая сортировка
Set<Integer> sortedNumbers = new TreeSet<>();
sortedNumbers.add(42);
sortedNumbers.add(10);
sortedNumbers.add(99);
System.out.println("Sorted set: " + sortedNumbers); // [10, 42, 99]
// Использование компаратора для обратной сортировки строк
Set<String> reverseSorted = new TreeSet<>(Comparator.reverseOrder());
reverseSorted.addAll(Arrays.asList("zebra", "apple", "mango"));
System.out.println("Reverse sorted: " + reverseSorted); // [zebra, mango, apple]
}
}
Когда использовать Set?
- Когда необходимо гарантировать уникальность коллекции (уникальные ID, логины, теги).
- Для эффективной проверки наличия элемента (
contains()работает за O(1) уHashSet). - Для выполнения операций над множествами: объединение (
addAll), пересечение (retainAll), разность (removeAll).