HashSet
HashSet — коллекция уникальных значений без порядка. Главное отличие от List: дубликаты не допускаются, и нет понятия “индекса” — нельзя достать элемент по номеру.
Set<String> tags = new HashSet<>();
tags.add("java");
tags.add("backend");
tags.add("java"); // повторно — просто игнорируется, уже есть
tags.size(); // 2, не 3
tags.contains("java"); // true
Используй HashSet, когда важно «есть это значение в наборе или нет» и не важен порядок — например, список уже посещённых страниц, набор уникальных id.
Копнуть глубже
Как HashSet понимает, что значение уже есть. Под капотом он построен на основе HashMap (HashSet хранит твои элементы как ключи HashMap, со значением-пустышкой). Чтобы это работало правильно, у класса элементов должны быть корректно переопределены equals() и hashCode() — иначе одинаковые по смыслу объекты HashSet посчитает разными. Подробнее — в теме «equals / hashCode».
contains() — почти мгновенный, в среднем O(1). Это главное преимущество перед List.contains(), который перебирает все элементы по очереди (O(n)). На больших объёмах разница огромная.
• почему `contains()` у `HashSet` быстрее, чем у `List` (если дошёл до 2-го слоя).