Collect key values from array to map without duplicates

Tags:



My app gets some string from web service. It’s look like this:

name=Raul&city=Paris&id=167136

I want to get map from this string:

{name=Raul, city=Paris, id=167136}

Code:

Arrays.stream(input.split("&"))
          .map(sub -> sub.split("="))
          .collect(Collectors.toMap(string-> string[0]), string -> string[1]));

It’s okay and works in most cases, but app can get a string with duplicate keys, like this:

name=Raul&city=Paris&id=167136&city=Oslo

App will crash with following uncaught exception:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key city (attempted merging values Paris and Oslo)

I tried to change collect method:

.collect(Collectors.toMap(tokens -> tokens[0], tokens -> tokens[1]), (r, strings) -> strings[0]);

But complier says no:

Cannot resolve method 'collect(java.util.stream.Collector<T,capture<?>,java.util.Map<K,U>>, <lambda expression>)'

And Array type expected; found: 'T'

I guess, it’s because I have an array. How to fix it?

Answer

You are misunderstanding the final argument of toMap (the merge operator). When it find a duplicate key it hands the current value in the map and the new value with the same key to the merge operator which produces the single value to store.

For example, if you want to just store the first value found then use (s1, s2) -> s1. If you want to comma separate them, use (s1, s2) -> s1 + ", " + s2.



Source: stackoverflow