Hi,

Another possibility would be to introduce the following default methods to Map.Entry:

public interface Map.Entry<K, V> {
...
    default <L> Map.Entry<L, V> withKey(L key) { ... }
    default <W> Map.Entry<K, W> withValue(W value) { ... }
}

Usage would then look like:

map.entrySet().stream().map(e -> e.withValue(e.getValue().transformed()))


i.e. I don't think there's a need for function-taking methods like mapKey/mapValue, because Map.Entry returning methods are not common in APIs (Iterator<Map.Entry>.next() is a rare exception)...

Optional returning methods OTOH are common in APIs, so function-taking methods on Optional are useful. Not so with Map.Entry, I think.

Regards, Peter


On 01/15/2016 02:37 PM, Remi Forax wrote:
Hi Stephan,
mixing methods that create a new entry (your mapValue) with one that mutate the 
current entry (setValue) is still a bad idea.

I think it's better to introduce a static method in Map.Entry like this:
   public static <K, V, R> Function<Map.Entry<K, V>, Map.Entry<K, R>> 
mapValue(Function<? super V, ? extends R> valueMapper) {
     return entry -> Map.entry(entry.getKey(), 
valueMapper.apply(entry.getValue()));
   }

and use it like this:
   map.entrySet().stream().map(mapValue(v -> v.transformed))

Also with the introduction of Map.entry() in 9, your "not really pleasant 
example" is a little better
   map.entrySet().stream().map(e -> entry(e.getKey(), e.getValue.transformed()))

regards,
Rémi

PS: in 9, you can use Map.entry() instead of new 
AbstractMap.SimpleImmutableEntry<>().

----- Mail original -----
De: "Stephen Colebourne" <scolebou...@joda.org>
À: "core-libs-dev" <core-libs-dev@openjdk.java.net>
Envoyé: Vendredi 15 Janvier 2016 14:05:51
Objet: Map.Entry methods for streams

I've had a morning of discussion about streaming Map this morning. While
there is clearly no appetite for a JDK MapStream right now, it does seem
that two additional methods on Map.Entry could help.

Two of the common cases when streaming over Map.Entry are to transform the
keys and to transform the values. Currently, the code is as follows:

hashMap.entrySet().stream()
   .map(e -> new AbstractMap.SimpleImmutableEntry(e.getKey(),
e.getValue().transformed()))
   ...

This isn't really very pleasant.

Adding a default method to Map.Entry would help:

hashMap.entrySet().stream()
   .map(e -> e.mapValue(v -> v.transformed()))
   ...

Implementation of the mapValue method is left to the reader, but it isn't
hard. A mapKey() method would also be needed. Note that both are designed
to work without mutating the map (returning a new entry).

Finally, the Collectors class could do with a new method entriesToMap()
that collects a stream of Map.Entry back into a Map.

While these proposals are not as powerful as a MapStream, they would smooth
some rough edges in the API when working with maps.

Stephen


Reply via email to