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