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