BiSupplier in Java8

Viewed 2449

I have seen BiConsumer, BiPredicate, BiFunction but not BiSupplier or similar. I tried the below code but got an exception saying:

"Multiple non-overriding abstract methods found in BiSupplier".

@FunctionalInterface
public interface BiSupplier<T, R> {

    /**
     * Gets a first.
     *
     * @return a first
     */
    T getFirst();


    /**
     * Gets a second.
     *
     * @return a second
     */
    R getSecond();
}

Can some please help me with this.

3 Answers

The concept between Function (Predicate or Consumer) is different over Supplier.

A simple explanation table:

  • Function transforms 1 input to 1 output. BiFunction transforms 2 inputs. So theoretically, there can be TriFunction etc...
  • Predicate works same like Function but the output is always boolean.
  • Consumer consumes 1 input and doesn't return anything (void). BiConsumer consumes 2 inputs. So theoretically, there can be TriConsumer etc...

Now, Supplier. The Supplier turns nothing (0 inputs) into an output. Notice the functional interfaces above provide either one (Function and Predicate) or none (Consumer) output.

Supplier creates something from nothing and as you know, it's not possible to have more than one return type. Theoretically BiSupplier would mean something like "Create something from two nothings" which in Java context makes no sense (however, "one nothing" does: Supplier<String> supplier = () -> "Hi";).

You can understand Supplier<T> as Function<Void, T> (doesn't work in practice, but the principle is same). Now, BiSupplier<T> would be BiFunction<Void, Void, T> which really doesn't make any sense.

A BiSupplier simply wouldn't make sense. Methods return a value of a single type in Java.

So you should simply create a class holding the two values and return that:

class MyValue<T, R> {
    private final T first;
    private final R second;

    // constructors, getters.
}

And then just use Supplier<MyValue<T,R>> instead of creating a new functional interface.

your code is wrong, you have annotated the interface with FunctionalInterface but it has got two abstract methods.

Related