Java:连接包含集合的映射的值



考虑以下伪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

最新更新