'How to convert a Map<String,List<String>> to Map<String,Set<String>> using forEach operation
I want to convert a Map<String,List<String>> to Map<String,Set<String>> for optimized search. I came up with the below traditional approach.
for (Map.Entry<String, List<String>> entry : this.mapWithList.entrySet()) {
Set<String> hSet = new HashSet<>(entry.getValue());
this.mapWithSet.put(entry.getKey(), hSet);
}
I am wondering how can I do it using forEach in Java 8.
Also, with the forEach lambda, will it be any better with the code performance?
Solution 1:[1]
will it be any better with the code performance?
No, it'll not. Iterative solutions are usually more performant.
how can I do it using
forEach
There's a special operation collect() in the Stream API that is meant to populate a mutable container (e.g. Collection, StringBuilder, etc.) with the contents of the stream pipeline. Usage of forEach() for that purpose is highly discouraged by the documentation. Consider utilizing forEach() only as a last resort, when there's no other way to achieve that.
To do that with collect(), first, you need to create a stream of entries.
Based on each entry, a new entry has to be created, map() operation is utilized for that purpose. Static method Map.entry() is used to instantiate a new entry.
And then apply the terminal operation collect() by passing Collectors.toMap() as parameter, which creates a collector (object responsible for placing the stream elements into a mutable container, a map in this case) based on the two provided functions (for keys and values).
main()
public static void main(String[] args) {
Map<String,List<String>> mapWithList =
Map.of("1", List.of("1", "2", "3"));
Map<String,Set<String>> result =
mapWithList.entrySet().stream()
.map(entry -> Map.entry(entry.getKey(),
new HashSet<>(entry.getValue())))
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue));
System.out.println(result);
}
Output
{1=[1, 2, 3]}
Solution 2:[2]
You can use this approach:
public static void main(String[] args) {
Map<String, List<String>> inputMap = new HashedMap<>();
List<String> a = new ArrayList<>();
a.add("a1");
a.add("a2");
inputMap.put("a", a);
List<String> b = new ArrayList<>();
b.add("b1");
b.add("b2");
inputMap.put("b", b);
System.out.println(inputMap);
Map<String, Set<String>> resultSet= inputMap.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey, e -> new HashSet<>(e.getValue())));
System.out.println(resultSet);
}
Solution 3:[3]
one line solution using gson! (or any other JSON serializer)
Map<String, Set<String>> result = gson.fromJson(gson.toJson(otherMap), Map.class);
both maps have the same JSON representation. think outside the box ;)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Sachin Bose |
| Solution 3 |
