Reputation: 911
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
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
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