1

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?

3 Answers 3

5

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]}
Sign up to request clarification or add additional context in comments.

6 Comments

for Map.Entry::getKey and Map.Entry::getValue I am getting Non-static method cannot be referenced from a static context. I am using this piece of code in a public constructor, which is not static. Also Map.Entry doesn't seem correct.
@Conquistador Seems like a type mismatch (compilation errors with method references aren't very helpful). Take a look carefully at the types (resulting variable and source). I've provided a complete runnable example in the answer.
@Conquistador If didn't find the cause of error, place these lambdas instead of method references Collectors.toMap(e -> e.getKey(), e -> e.getValue()) a then read the compile error - it'll be more informative.
@Conquistador Map.Entry doesn't seem correct - Entry is a nested interface that recedes inside the Map interface. Map.Entry - is a correct syntax to refer to it.
There’s no need for this map step. Just use mapWithList.entrySet().stream() .collect( Collectors.toMap(Map.Entry::getKey, entry -> new HashSet<>(entry.getValue()))); Note that the Map.entry(…) method requires Java 9, but as said, the map step is obsolete anyway.
|
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);
    }

Comments

-1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.