4

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.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
Alex Man
  • 4,746
  • 17
  • 93
  • 178

3 Answers3

11

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.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
2

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.

ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • if `Supplier>` is in the function parameter, how do we pass the values – Alex Man Mar 09 '21 at 15:17
  • The `MyValue` class needs constructors and getters. If I understand you correctly, you would call the function with `myFunction(() -> new MyValue<>(stringA, stringB))` or something like that, depending on how you're sourcing the values. But that constructor must first be declared to initialize the values. – ernest_k Mar 09 '21 at 15:20
0

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

Thomson Ignesious
  • 689
  • 1
  • 8
  • 25