jOOQ / jOOL

jOOλ - The Missing Parts in Java 8 jOOλ improves the JDK libraries in areas where the Expert Group's focus was elsewhere. It adds tuple support, function support, and a lot of additional functionality around sequential Streams. The JDK 8's main efforts (default methods, lambdas, and the Stream API) were focused around maintaining backwards compatibility and implementing a functional API for parallelism.
http://www.jooq.org/products
Apache License 2.0
2.08k stars 167 forks source link

Have Seq.seq(Map) provide a mapValues #257

Closed stephenh closed 8 years ago

stephenh commented 8 years ago

Mapping values is a very common operation; right now it requires:

    Map<Long, Long> m = new HashMap<>();
    m.put(1L, 2L);
    Map<Long, Long> m2 = Seq.toMap(Seq.seq(m).map(e -> Tuple.tuple(e.v1, e.v2 * 2)));

In theory I'd like to do:

    Map<Long, Long> m2 = seq(m).mapValues(v -> v * 2);

If the Seq.seq(Map) method returned some sort of MapSeq subclass of Seq, it could provide Map/tuple-aware methods like mapValues.

stephenh commented 8 years ago

I guess technically mapValues would probably result a Seq<Tuple<K, V>> or MapSeq<K, V>, which means mapValues in my example might need another toMap (which granted is already taken) to get it back to a Map type:

    Map<Long, Long> m2 = seq(m).mapValues(v -> v * 2).toMap();
stephenh commented 8 years ago

A coworker pointed out I'm abusing Seq when I really have a map, so probably want something like:

https://github.com/javaslang/javaslang/blob/master/javaslang/src/main/java/javaslang/collection/Map.java#L183

bendem commented 8 years ago

So basically Map#replaceAll(BiFunction)?

map.replaceAll((k, v) -> v * 2);
stephenh commented 8 years ago

Haha, yes! Today I learned. :-)

That said, I still wouldn't mind a Seq.mapValues-style way of doing it.

lukaseder commented 8 years ago

Note, there's Tuple2.map2() which might be a bit more useful in your case, although I absolutely agree with @bendem that a replaceAll() call is optimal in this particular situation.

I'm not sure if a new MapSeq type would do the trick. I feel that it is too specific to be really useful. I much prefer a Seq2 type as suggested here: https://github.com/jOOQ/jOOL/pull/172. The only difference being that a MapSeq would have unique keys. With Seq2, your mapValues() method would simply become a map2() method, or a map((k, v) ->tuple(k, v * 2)) call.

Unfortunately, both MapSeq and Seq2 are not trivial to introduce into the type system in a backwards-compatible way, but with the additional use-case in mind, I will think that Seq2 will really add value to jOOλ. I'm closing this issue as a duplicate of #172