I have a code that filters some elements from one list and then need to perform two operations on the filtered stream.
One way to perform this is to use a lambda that does any number of operations.
List a, b, c; // initialize and fill the lists
a.stream()
//filtering
.forEach(e -> {
b.add(e);
c.remove(e);
});
Is there a way both operations can be performed? For example if the forEach
method could take multiple arguments.
.forEach(b::add, c::remove);
You could chain a series of consumers to achieve handling any length of stream with single forEach
step and avoiding use of intermediate toList()
. The first Consumer to forEach
would need to be declared as a local variable before appling andThen(nextOperation)
. For example, if say, with List<String> a
:
Consumer<String> x = b::add;
a.stream().forEach(x.andThen(c::remove));
For convenience it is also possible to setup a method to chain as one consumer:
a.stream().forEach(combine(List.of(b::add,c::remove)));
// or
a.stream().forEach(combine(b::add,c::remove));
and implement something like this:
public static <T> Consumer<T> combine(List<Consumer<T>> consumers) {
return consumers.stream().reduce(Consumer::andThen).orElse(x -> {});
}
// or
public static <T> Consumer<T> combine(Consumer<T> ... args) {
return Arrays.stream(args).reduce(Consumer::andThen).orElse(x -> {});
}