考虑以下伪Map<String, Set<String>>
:
{
"1": ["A", "B"],
"2": ["A", "C"],
"3": ["D", "B", "A", "C"],
"4": ["C", "A", "B"],
"5": ["A", "B"],
}
将值Set连接到单个Set中的最佳方法是什么(上面的示例应该是["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);
}
}
但这感觉有点丑陋,我想知道是否有更好的(更"内置"的(方法来做到这一点?
使用Set.addAll(Collection)
方法;请参阅javadoc。
Collection<Set<String>> values = myMap.values();
Set<String> unique = new HashSet<>();
for (Set<String> v : values) {
unique.addAll(v);
}
逻辑应该是不言自明的。
元课程:通过浏览javadocs来熟悉所使用的API的功能是一个好主意。
实际上,您不必检查Set
是否已经包含要添加的值。这就是为什么你首先要使用一套。
如果此集合已经包含元素,则调用保持该集合不变并返回false。
来自Set#add(E)
Javadoc
请记住,您所要做的唯一一件事就是实际遍历Set
,并将值组合到一个集合中,而不必担心重复。
已经提供了一个通过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