This is just a theorical question with no concrete application.
I have the following method which I will not touch. It could (if possible at all) be used as a BiConsumer
.
void doSmallThing(A a, B b) {
// do something with a and b.
}
void doBigThing(List<A> as, B b) {
// What to do?
}
How can I iterate on as
while keeping b
constant and use this::doSmallThing
in doBigThing
?
Of course the following doesn't work.
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(this::doSmallThing);
}
The following works nice and is actually what I use everyday.
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(a -> doSmallThing(a, b));
}
The following also works well, but is a bit more tricky.
Consumer<A> doSmallThingWithFixedB(B b) {
return (a) -> doSmallThing(a, b);
}
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(doSmallThingWithFixedB(b))
}
But all of those solutions don't get the simplicity of the Consumer
case. So is there anything simple that exists for BiConsumer
?
You want to "bind" the function argument. Unfortunately there's no built-in mechanism to do this in Java 8 (except binding the object for instance methods like this::
). You may generalize your doSmallThingWithFixedB
method like this:
public class Bind {
public static <A, B> Consumer<A> bindLast(BiConsumer<A, B> fn, B b) {
return a -> fn.accept(a, b);
}
public static <A, B> Consumer<B> bindFirst(BiConsumer<A, B> fn, A a) {
return b -> fn.accept(a, b);
}
}
And use:
void doBigThing(List<A> as, B b) {
as.stream()
.forEach(Bind.bindLast(this::doSmallThing, b));
}
Probably there's some third-party library which already contains such methods. However using explicit lambda seems ok for me. You should not try to express everything with method references.
BiConsumers are used when iterating over Map entries for example:
Map<A, B> map = ...;
map.forEach(this::doSomething);
Stream.collect()
also takes BiConsumers as arguments, but it's used less often than an iteration on map entries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With