Assuming that the Map
itself is mutable, you use something like
map.replaceAll((key, set) -> new HashSet<>(set));
Example:
Map<Integer,Set<Object>> map = new HashMap<>();
map.put(5, Collections.emptySet());
map.put(10, Collections.singleton("foo"));
map.replaceAll((key, set) -> new HashSet<>(set));
map.get(5).add(42);
map.get(10).add("bar");
map.entrySet().forEach(System.out::println);
5=[42]
10=[bar, foo]
Of course, you can also replace new HashSet<>(set)
with new TreeSet<>(set)
or generally every Set
implementation type following the copy constructor convention. When you can’t use a copy constructor, you have to resort to addAll
, e.g.
map.replaceAll((key, set) -> {
TreeSet<Object> newSet = new TreeSet<>(Comparator.comparing(Object::toString));
newSet.addAll(set);
return newSet;
});
There’s another option. Instead of converting all values of the map, only convert the sets on demand, i.e. when you actually want to modify them and they turn out not to have the intended type:
Map<Integer,Set<Object>> map = new HashMap<>();
map.put(5, Collections.emptySet());
map.put(10, Collections.singleton("foo"));
map.computeIfPresent(5, (key,set)->set instanceof HashSet? set: new HashSet<>()).add(42);
map.computeIfPresent(10, (key,set)->set instanceof HashSet?set:new HashSet<>()).add("bar");
map.entrySet().forEach(System.out::println);