I'm using Java 8 along with the Pair from Apache Commons Lang3.
The first thing I am trying to do is get a stream from a List<T>
and to take a Function<T,U>
and ultimately create a List<Pair<T,U>>
. Currently I am creating a Function<T,Pair<T,U>>
with the specific types I want and using this to map the stream. What I want is something like:
public static <T, U> Function<T, Pair<T, U>> tupledResult(final Function<T, U> generator) {
Objects.requireNonNull(generator);
return (T t) -> new ImmutablePair<>(t, generator.apply(t));
}
The next problem is that now that I have a List<Pair<T, U>>
I want to be able to use foreach
to apply a BiConsumer<T,U>
(similar to the tupled
function in Scala). I guess it would look like:
public static <T, U> Consumer<Pair<T, U>> tupled(final BiConsumer<T, U> consumer) {
Objects.requireNonNull(consumer);
return (final Pair<T, U> p) -> consumer.accept(p.getLeft(), p.getRight());
}
Is there anything in Apache Commons Lang3 that does this or should I roll my own? If the later, is this something that is useful to contribute or is this a bad solution?
Example
This is the sort of thing I want to achieve:
private void doStuff(final List<Thing> things) {
final List<Pair<Thing, Other>> otherThings = things.stream()
.map(tupledResult(ThingHelper::generateOther))
.collect(Collectors.toList());
otherThings.stream().forEach(tupled((final Thing thing, final Other other) -> {
doSomething(thing, other);
}));
otherThings.stream().forEach(tupled((final Thing thing, final Other other) -> {
doSomethingElse(thing, other);
}));
}
The points here are that ThingHelper.generateOther
is relatively expensive and I only want to do it once. Also doSomething
must be applied to everything first and then doSomethingElse
afterwards.
The pairs never leave the scope of this method nor do I want to overload the methods to take a pair. In this case I really don't care about the lack of semantics of the pair, all that matters is the order. doSomething
and doSomethingElse
are the ones providing the semantics.