Matt
Matt

Reputation: 911

Using a stream to produce a tuple of lists from a list of tuples

I am trying to find how to create a tuple of lists from a list of tuples. for example

f(list<tuple<u,v>>) => tuple<list<u>,list<v>>

This use case does not appear to be accommodated well by the standard API. Other articles say to use reduce, but this does not work since it will only return the same type as the input type.

In .net I would use Enumerable.Aggregate to achieve this.

Is there a functional way to achieve this in java?

Upvotes: 3

Views: 2336

Answers (2)

Alexander Pavlov
Alexander Pavlov

Reputation: 2220

Java12 will provide Collectors.teeing which allows to apply two collectors and then merge their results

Meanwhile, you can apply reduce

Tuple<List<U>,List<V>> tupleOfLists = listOfTuples
  .stream()
  .reduce(
    new Tuple<List<U>,List<V>>(new ArrayList<U>(), new ArrayList<V>()),
    (tupleOfLists, tuple) -> {
      tupleOfLists.left().add(tuple.left());          
      tupleOfLists.right().add(tuple.right());
      return tupleOfLists;
    },
    (tupleOfLists1, tupleOfLists2) -> {
      tupleOfLists1.left().addAll(tupleOfLists2.left());
      tupleOfLists1.right().addAll(tupleOfLists2.right());
      return  tupleOfLists1;
    }
  );

Upvotes: 4

moilejter
moilejter

Reputation: 998

It seems you would need to use Java 12, to write something like:

listOfTuples.stream().collect(teeing(
  map(t -> t.u).collect(Collectors.toList()),
  map(t -> t.v).collect(Collectors.toList()), 
  (us, vs) -> new Tuple(us,vs)
 ));

Haven't done this myself - just found a similare example here: https://www.baeldung.com/java-8-collectors

Upvotes: 1

Related Questions