Skip to content

Java: join the values of a map containing sets

Consider the following pseudo Map<String, Set<String>>:

{
    "1": ["A", "B"],
    "2": ["A", "C"],
    "3": ["D", "B", "A", "C"],
    "4": ["C", "A", "B"],
    "5": ["A", "B"],
}

What is the best way to join the value Sets into a single Set (above example should be ["A", "B", "C", "D"]). The order of the resulting set does not matter.

I know that I can to something like this:

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);
    }
}

But it feels kind of ugly and I’m wondering if there is a better (and more “built-in”) way of doing this?

Answer

Use the Set.addAll(Collection) method; see the javadoc.

Collection<Set<String>> values = myMap.values();
Set<String> unique = new HashSet<>();

for (Set<String> v : values) {
    unique.addAll(v);
}

The logic should be self-evident.

Meta-lesson: it is a good idea to familiarize yourself with the capabilities of the APIs that you use by skim-reading the javadocs.