#java #dictionary #set
Вопрос:
Рассмотрим следующие псевдо Map<String, Set<String>>
:
{
"1": ["A", "B"],
"2": ["A", "C"],
"3": ["D", "B", "A", "C"],
"4": ["C", "A", "B"],
"5": ["A", "B"],
}
Каков наилучший способ объединить наборы значений в один набор (должен быть приведен пример выше ["A", "B", "C", "D"]
). Порядок результирующего набора не имеет значения.
Я знаю, что могу сделать что-то подобное:
Collection<Set<String>> values = myMap.values();
Set<String> unique = new HashSet<>();
for (Set<String> v : values) {
for (String s : v) {
if (!unique.contains(s)) unique.add(s);
}
}
Но это кажется немного уродливым, и мне интересно, есть ли лучший (и более «встроенный») способ сделать это?
Комментарии:
1. Прежде всего, вам не нужно проверять, содержит ли набор уже значение, которое вы собираетесь добавить. Набору все равно, и он просто проигнорирует, если значение уже присутствует.
Ответ №1:
Используйте этот Set.addAll(Collection)
метод; см. javadoc.
Collection<Set<String>> values = myMap.values();
Set<String> unique = new HashSet<>();
for (Set<String> v : values) {
unique.addAll(v);
}
Логика должна быть самоочевидной.
Мета-урок: рекомендуется ознакомиться с возможностями API, которые вы используете, просматривая javadocs.
Ответ №2:
На самом деле вам не нужно проверять, содержит ли a Set
уже значение, которое вы собираетесь добавить. Вот почему вы в первую очередь хотели бы использовать набор.
Если этот набор уже содержит элемент, вызов оставляет набор неизменным и возвращает значение false.
Имея это в виду, единственное, что вам нужно будет сделать, это на самом деле просмотреть свои Set
s и объединить значения в один набор, не беспокоясь о дубликатах.
Одно решение via addAll()
уже было предоставлено, поэтому я подумал, что предложу альтернативное решение с использованием потоков Java 8:
Set<String> unique = myMap.values() // gets the values (all sets) from the map
.stream() // stream of values
.flatMap(Set::stream) // flattens all sets (in values) in to single stream
.collect(Collectors.toSet()); // collects the values into single set