Is there a way to use BiConsumers as easy as consumers?

This is just a theoretical question without specific application.

I have the following method, which I will not touch. It could (if possible at all) be used as 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 repeat on as, keeping constant band use this::doSmallThingin doBigThing?

Of course, the following does not work.

void doBigThing(List<A> as, B b) {
  as.stream()
  .forEach(this::doSmallThing);
}

The following works well and actually I use every day.

void doBigThing(List<A> as, B b) {
  as.stream()
  .forEach(a -> doSmallThing(a, b));
}

The following also works well, but a little more complicated.

Consumer<A> doSmallThingWithFixedB(B b) {
  return (a) -> doSmallThing(a, b);
}

void doBigThing(List<A> as, B b) {
  as.stream()
  .forEach(doSmallThingWithFixedB(b))
}

But all these solutions do not get the simplicity of the case Consumer. So, is there something simple for BiConsumer?

+4
source share
3 answers

"" . , Java 8 ( , , this::). doSmallThingWithFixedB :

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);
    }
}

:

void doBigThing(List<A> as, B b) {
  as.stream()
    .forEach(Bind.bindLast(this::doSmallThing, b));
}

, , . . .

+5

BiConsumers , :

Map<A, B> map = ...;
map.forEach(this::doSomething);

Stream.collect() BiConsumers , , .

+1

Add a method doSmallThingto B:

class B {
    public void doSmallThing(A a) {
         YourClass.doSmallThing(a, this); // You may want to inline this.
    }
}

and name it doBigThing:

void doBigThing(List<A> as, B b) {
    as.stream()
        .forEach(b::doSmallThing);
}
0
source

All Articles