public
by default
public
abstract
by default
abstract
itself or must provide an implementationpublic static final
interface Foo {
int foo(); // public abstract
int FOO = 42; // public static final
}
class FooImpl implements Foo {
@Override
public int foo() { // must be public!
return FOO; // 42
}
}
default
modifierinterface Foo {
default int foo() {
return 42;
}
}
class FooImpl implements Foo {
// no need to override foo!
void bar() {
Foo f = new FooImpl();
f.foo(); // 42
}
}
public
by default
public
although it is simply redundantprivate
or protected
static
, final
or abstract
interface Foo {
default int foo() {
return 42;
}
}
interface Bar {
default int foo() {
return -42;
}
}
class FooBar implements Foo, Bar {
public int foo() {
return 0;
}
// It would not make any difference if either Foo.foo or Bar.foo was abstract
}
class FooBar implements Foo, Bar {
public int foo() {
return Foo.super.foo(); // super weird syntax!
}
}
interface Foo {
default int foo() {
return 42;
}
}
class Bar {
public int foo() {
return -42;
}
}
class FooBar extends Bar implements Foo {
void fooBar() {
foo(); // -42
}
}
interface Bar {
static void bar() {}
}
class Foo {
void foo() {
Bar.bar(); // No other way
}
}
interface Foo {
static void foo() {}
}
class FooImpl implements Foo {
void fooTest() {
// This is not allowed:
// foo();
// Correct way is:
Foo.foo(); // No other way
}
}
interface Foo {
static void foo() {}
}
interface Bar extends Foo {}
// This will not compile:
// Bar.foo();
class Foo {
static void foo() {}
}
class Bar extends Foo {}
// This compiles and runs fine:
Bar.foo();
java.lang.Object
do not count@FunctionalInterface
interface Foo {
// single abstract method
void foo();
// equals method here is fine, it is inherited from the Object class
boolean equals(Object o);
}
class FooImpl implements Foo {
@Override
public void foo(){}
// Implementing Foo does not mean equals method must be implemented
}
Interface | SAM | Arguments | Returns |
---|---|---|---|
Predicate | test | T | boolean |
BiPredicate | test | T, U | boolean |
Consumer | accept | T | void |
BiConsumer | accept | T, U | void |
Supplier | get | T | |
Function | apply | T | R |
UnaryOperator | apply | T | T |
BiFunction | apply | T, U | R |
BinaryOperator | apply | T, T | T |
1 Single Abstract Method
* Purely Primitive Interfaces are Printed in Bold
Interface | SAM | Arguments | Returns |
---|---|---|---|
Predicate | |||
IntPredicate | test | int | boolean |
LongPredicate | test | long | boolean |
DoublePredicate | test | double | boolean |
Consumer | |||
IntConsumer | accept | int | void |
LongConsumer | accept | long | void |
DoubleConsumer | accept | double | void |
BiConsumer | |||
ObjIntConsumer | accept | T, int | void |
ObjLongConsumer | accept | T, long | void |
ObjDoubleConsumer | accept | T, double | void |
Supplier | |||
IntSupplier | getAsInt | int | |
LongSupplier | getAsLong | long | |
DoubleSupplier | getAsDouble | double | |
BooleanSupplier | getAsBoolean | boolean | |
Function | |||
IntFunction | apply | int | R |
LongFunction | apply | long | R |
DoubleFunction | apply | double | R |
ToIntFunction | applyAsInt | T | int |
ToLongFunction | applyAsLong | T | long |
ToDoubleFunction | applyAsDouble | T | double |
IntToDoubleFunction | applyAsDouble | int | double |
IntToLongFunction | applyAsLong | int | long |
LongToIntFunction | applyAsInt | long | int |
LongToDoubleFunction | applyAsDobule | long | double |
DoubleToIntFunction | applyAsInt | double | int |
DoubleToLongFunction | applyAsLong | double | long |
UnaryOperator | |||
IntUnaryOperator | applyAsInt | int | int |
LongUnaryOperator | applyAsLong | long | long |
DoubleUnaryOperator | applyAsDouble | double | double |
BiFunction | |||
ToIntBiFunction | applyAsInt | T, U | int |
ToLongBiFunction | applyAsLong | T, U | long |
ToDoubleBiFunction | applyAsDouble | T, U | double |
BinaryOperator | |||
IntBinaryOperator | applyAsInt | int, int | int |
LongBinaryOperator | applyAsLong | long, long | long |
DoubleBinaryOperator | applyAsDouble | double, double | double |
Predicates can be chained with and
, or
and negate
as seen below.
List<String> s = new ArrayList<>(Arrays.asList("foo", "foof", "boo", "boob"));
Predicate<String> startsF = s -> s.toLowerCase().charAt(0) == 'f';
Predicate<String> endsF = s -> s.toLowerCase().charAt(s.length() - 1) == 'f';
s.removeIf(startsF.and(endsF).negate()); // [foof]
You can not chain Consumer
s with BiConsumer
s, but you can chain Function
s with BiFunction
s.
// An example of chaining a BiFunction with a Function
BiFunction<String, Integer, String> biFunction = (s, integer) -> s + integer;
Function<String, String> function = s -> s.toLowerCase();
biFunction.andThen(function).apply("APPEND", 42); // append42
// An example of chaining Consumers
Consumer<StringBuilder> trimmer = s -> s.deleteCharAt(0);
Consumer<StringBuilder> doubler = s -> s.append(s.toString());
StringBuilder sb = new StringBuilder("kkoray");
trimmer.andThen(doubler).accept(sb); // koraykoray
import java.util.function.BiPredicate;
class FooBar {
static class Foo {int foo = 42;}
static class Bar {int bar = 42;}
public static <T, U> boolean foo(T t, U u, BiPredicate<T,U> biPredicate) {
return biPredicate.test(t, u);
}
public static void main(String[] args) {
foo(new Foo(), new Bar(), (foo, bar) -> foo.foo == 42 && bar.bar == 42);
// true
}
}