Что такое Set в Java и для чего он используется?

«Что такое Set в Java и для чего он используется?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Set<E> — это коллекция в Java, которая не допускает дублирования элементов. Ее основная контрактная обязанность — гарантировать уникальность хранимых объектов.

Ключевые характеристики:

  • Уникальность: Не может содержать двух равных элементов (равенство определяется методами equals() и hashCode()).
  • Порядок: Не гарантирует порядок элементов, если не используется специальная реализация.
Основные реализации и их особенности: Реализация Внутренняя структура Порядок Время доступа Сортировка
HashSet Хэш-таблица (HashMap) Не гарантирован O(1) в среднем Нет
LinkedHashSet Хэш-таблица + связный список Порядок вставки O(1) в среднем Нет
TreeSet Красно-черное дерево Натуральный порядок или Comparator O(log n) Да

Практические примеры использования:

  1. Удаление дубликатов из списка:

    List<String> listWithDuplicates = Arrays.asList("A", "B", "A", "C");
    Set<String> setWithoutDuplicates = new HashSet<>(listWithDuplicates);
    System.out.println(setWithoutDuplicates); // Вывод: [A, B, C] (порядок может быть другим)
  2. Проверка на уникальность:

    Set<String> usernames = new HashSet<>();
    if (!usernames.add("john_doe")) {
        System.out.println("Имя пользователя уже занято!");
    }
    // Метод add() возвращает false, если элемент уже был в множестве.
  3. Множественные операции (объединение, пересечение):

    Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
    Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 4, 5));
    
    // Объединение
    Set<Integer> union = new HashSet<>(set1);
    union.addAll(set2); // union = {1, 2, 3, 4, 5}
    
    // Пересечение
    Set<Integer> intersection = new HashSet<>(set1);
    intersection.retainAll(set2); // intersection = {3}

Важно: Для корректной работы объектов в HashSet или LinkedHashSet должны быть правильно переопределены методы equals() и hashCode(). TreeSet требует, чтобы элементы реализовывали Comparable или передавался Comparator.