Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BiSupplier in Java8

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.

like image 574
Alex Man Avatar asked Dec 23 '22 15:12

Alex Man


2 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.

like image 60
Nikolas Charalambidis Avatar answered Jan 02 '23 16:01

Nikolas Charalambidis


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.

like image 39
ernest_k Avatar answered Jan 02 '23 16:01

ernest_k