Интерфейс Set
Set<E> — коллекция, которая запрещает дубликаты: метод add(e) возвращает false, если такой элемент уже есть. По математической модели Set — это множество.
Реализации различаются порядком хранения и стоимостью операций:
HashSet— основан на хэш-таблице. Порядок элементов не определён.add,remove,containsзаO(1)в среднем.LinkedHashSet— сохраняет порядок вставки. Чуть медленнееHashSet.TreeSet— отсортированное множество (SortedSet/NavigableSet). Операции заO(log n).EnumSet— компактное множество для значенийenum.
Иерархия
Collection<E>
└── Set<E>
├── HashSet<E>
│ └── LinkedHashSet<E>
├── SortedSet<E>
│ └── NavigableSet<E>
│ └── TreeSet<E>
└── EnumSet<E>
Пример 1. HashSet — устранение дубликатов
import java.util.HashSet;
import java.util.Set;
public class SetHashDemo {
public static void main(String[] args) {
Set<String> sensors = new HashSet<>();
sensors.add("HC-SR04");
sensors.add("DHT22");
sensors.add("HC-SR04"); // дубликат
sensors.add("MPU6050");
System.out.println("Размер: " + sensors.size());
System.out.println("Множество: " + sensors);
}
}
Output:
Размер: 3
Множество: [MPU6050, DHT22, HC-SR04]
Пример 2. LinkedHashSet — порядок вставки
import java.util.LinkedHashSet;
import java.util.Set;
public class SetLinkedDemo {
public static void main(String[] args) {
Set<String> path = new LinkedHashSet<>();
path.add("start");
path.add("checkpoint");
path.add("turn");
path.add("finish");
path.add("start"); // не добавится
for (String step : path) {
System.out.println(step);
}
}
}
Output:
start
checkpoint
turn
finish
Пример 3. TreeSet — отсортированное множество
import java.util.TreeSet;
public class SetTreeDemo {
public static void main(String[] args) {
TreeSet<Integer> distances = new TreeSet<>();
distances.add(45);
distances.add(12);
distances.add(87);
distances.add(30);
System.out.println("Отсортировано: " + distances);
System.out.println("Минимум: " + distances.first());
System.out.println("Максимум: " + distances.last());
System.out.println("Ближайшее снизу к 50: " + distances.floor(50));
System.out.println("Ближайшее сверху к 50: " + distances.ceiling(50));
}
}
Output:
Отсортировано: [12, 30, 45, 87]
Минимум: 12
Максимум: 87
Ближайшее снизу к 50: 45
Ближайшее сверху к 50: 87
Пример 4. Операции над множествами
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class SetOperations {
public static void main(String[] args) {
Set<String> a = new HashSet<>(Arrays.asList("D2", "D4", "D5"));
Set<String> b = new HashSet<>(Arrays.asList("D5", "D6", "D8"));
Set<String> union = new HashSet<>(a);
union.addAll(b);
Set<String> inter = new HashSet<>(a);
inter.retainAll(b);
Set<String> diff = new HashSet<>(a);
diff.removeAll(b);
System.out.println("Объединение: " + union);
System.out.println("Пересечение: " + inter);
System.out.println("Разность A\\B: " + diff);
}
}
Output:
Объединение: [D2, D4, D5, D6, D8]
Пересечение: [D5]
Разность A\B: [D2, D4]
Пример 5. EnumSet для режимов робота
import java.util.EnumSet;
import java.util.Set;
public class SetEnumDemo {
enum Mode { MANUAL, AUTO, LINE, OBSTACLE, IR }
public static void main(String[] args) {
Set<Mode> active = EnumSet.of(Mode.AUTO, Mode.LINE);
System.out.println("Активные: " + active);
System.out.println("Авто? " + active.contains(Mode.AUTO));
Set<Mode> all = EnumSet.allOf(Mode.class);
System.out.println("Все режимы: " + all);
}
}
Output:
Активные: [AUTO, LINE]
Авто? true
Все режимы: [MANUAL, AUTO, LINE, OBSTACLE, IR]
Подводные камни
Для корректной работы
HashSetтип элементов обязан правильно реализоватьhashCode()иequals(). Иначе одинаковые объекты будут считаться разными.TreeSetтребует, чтобы элементы реализовывалиComparableили был переданComparator. Иначе —ClassCastException.HashSetне гарантирует порядка обхода — порядок может меняться от версии JVM.nullвTreeSetзапрещён, вHashSet— допускается один.Не изменяйте поля объекта после добавления в
HashSet, если эти поля участвуют вhashCode().
См. также
Примечание
Материал подготовлен на основе официального руководства Oracle The Collections Framework и распространяется на условиях Oracle Free Documentation License. Тексты переписаны своими словами, примеры кода — оригинальные.