Map.replaceAll when changing value types
Brian Goetz
brian.goetz at oracle.com
Tue Apr 22 12:42:56 UTC 2014
Its a fair question. Certainly the stream construction you suggest will do the job; you’re looking for a more compact way to do it. Note that of course you could write your own static method that encapsulates the stream operation and you’d be done.
Map.replace/replaceAll are in-place, mutative methods, and so make sense as instance methods on Map. What you want is a “construct a new map”, which is more of a static factory. Two reasons it was not prioritized: (a) as a static method, anyone can write it, and put it anywhere, so omitting it from the JDK doesn’t really prevent anyone from doing this, and (b) as a static method, there’s no value in having specialized implementations in the various JDK Map implementations.
On Apr 22, 2014, at 6:10 AM, Frank van Heeswijk <fvheeswijk at outlook.com> wrote:
>
>
>
>
> Hello,
>
> First of all, this is the first time I am sending a mail to any java mailing list, so please correct me if I did something wrong.
>
> I am a regular visitor and answered on stackoverflow ( http://stackoverflow.com/users/2057294/skiwi ) and noticed that there are quite a large amount of questions now already asking for a way to easily replace values in maps when their type fundamentally changes.
> I however also have a few concerns while doing this, which will be listed below.
>
> Take first as example the following code, it may not be the best example, but it should show the intention:
>
> Map<String, Integer> map = new HashMap<>();
> map.put("test", 5);
> Map<String, String> mapped = map.entrySet().stream()
> .collect(Collectors.toMap(Map.Entry::getKey, entry -> String.valueOf(entry.getValue())));
>
> The intention here was to map the integer values to their string counterparts in a single map, functionally this is equivalent to the following:
>
> Map<String, Integer> map = new HashMap<>();
> map.put("test", 5);
> map.replaceAll((k, v) -> v + 1);
>
> One would expect the first case to also be a one-liner, possibly somewhat like:
>
> Map<String, String> mapped = map.replaceAllSpecial((k, v) -> String.valueOf(v));
>
> Based on this I have the following concerns:
> 1. How would the method exactly need to look like? Should it also have the option to take a Function<V_IN, V_OUT> valueMapper as argument?
> 2. How could this be optimized? Surely we do not *really* want to take all map entries out of one map and insert the modified value in a new map, I was thinking that an in-place modification would be the best, but then you have the issue where the type changes.
>
> Lastly, I hope that we can agree on that for such a trivial usecase, the usage of streams is possibly too complicated and furthermore point (2) is very important.
>
> As some more reference, here are some of the stackoverflow questions that ask for it:
> - http://stackoverflow.com/questions/23213891/how-to-map-values-in-a-map-in-java-8
> - http://stackoverflow.com/questions/22840170/in-java-8-functional-style-how-can-i-map-the-values-over-a-java-util-map
>
> Regards,
>
> Frank van Heeswijk
>
More information about the core-libs-dev
mailing list