default
) à toutes ces méthodes.@FunctionalInterface
" pour être explicite sur le fait qu'il s'agit d'une interface fonctionnelle.
Par défaut, les interfaces qui déclarent une seule méthode abstraite, sont considérées des interfaces fonctionnelles.java.util.function.Predicate
@FunctionalInterface public interface Predicate<T> { boolean test(T t); default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } default Predicate<T> negate() { return (t) -> !test(t); } default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } static <T> Predicate<T> isEqual(Object targetRef) { return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); } }
java.util.function
":Predicate<T>: boolean test(T t)
boolean test(T t)
"
qui declare un seul paramètre ("t" de type "T") et retourne vrais/faux.
L'implementation doit, typiquement, appliquer une logique autour de la valeur de l'argument "t".Predicate<Integer> isOdd = t -> t % 2 == 0; System.out.println(isOdd.test(1)); Predicate<Integer> isEven = isOdd.negate(); System.out.println(isEven.test(1));
IntPredicate: boolean test(int t)
LongPredicate: boolean test(long t)
DoublePredicate: boolean test(double t)
BiPredicate<T, U>: boolean test(T t, U u)
boolean test(T t, U u)
"
qui declare deux paramètres ("t" de type "T", "u" de type "U") et retourne vrais/faux.
L'implementation doit, typiquement, appliquer une logique autour de la valeur des arguments "t" et "u".BiPredicate<Object, Object> equals = (a, b) -> Objects.equals(a, b); System.out.println(equals.test(1, 2)); BiPredicate<Object, Object> deepEquals = Objects::deepEquals; System.out.println(deepEquals.test(1, 2));
Consumer<T>: void accept(T t)
void accept(T t)
"
qui declare un seul paramètre ("t" de type "T") et ne retourne pas de valeur.
L'implementation doit, typiquement, consommer la valeur de l'argument "t" et produit un effet de bord sans retourner de valeur.Consumer<String> println = t -> System.out.println(t); println.accept("test");
IntConsumer: void accept(int t)
LongConsumer: void accept(long t)
DoubleConsumer: void accept(double t)
BiConsumer<T, U>: void accept(T t, U u)
void accept(T t, U u)
"
qui declare deux paramètres ("t" de type "T", "u" de type "U") et ne retourne pas de valeur.
L'implementation doit, typiquement, consommer les valeurs des arguments "t" et "u" et produit un effet de bord sans retourner de valeur.BiConsumer<String, String> printlnIfElse = (a, b) -> System.out.println(a == null ? b : a); printlnIfElse.accept(null, "test");
ObjIntConsumer<T>: void accept(T t, int u)
ObjLongConsumer<T>: void accept(T t, long u)
ObjDoubleConsumer<T>: void accept(T t, double u)
Supplier<T>: T get()
T get()
" qui ne declare aucun paramètre et l'implementation doit fournir une valuer de type "T".Supplier<Double> random = () -> Math.random(); System.out.println(random.get());
BooleanSupplier: boolean getAsBoolean()
IntSupplier: int getAsInt()
LongSupplier: long getAsLong()
DoubleSupplier: double getAsDouble()
Function<T, R>: R apply(T t)
R apply(T t)
"
qui declare un seul paramètre ("t" de type "T") et retourne une valeur de type "R".
L'implementation doit, typiquement, appliquer une logique autour de la valeur de l'argument "t".Function<Integer, String> valueOf = t -> "id-".concat(String.valueOf(t)); System.out.println(valueOf.apply(15));
IntFunction<R>: R apply(int t)
LongFunction<R>: R apply(long t)
DoubleFunction<R>: R apply(double t)
ToIntFunction<T>: int applyAsInt(T t)
ToLongFunction<T>: long applyAsLong(T t)
ToDoubleFunction<T>: double applyAsDouble(T t)
IntToLongFunction: long applyAsLong(int t)
IntToDoubleFunction: double applyAsDouble(int t)
LongToIntFunction: int applyAsInt(long t)
LongToDoubleFunction: double applyAsDouble(long t)
DoubleToIntFunction: int applyAsInt(double t)
DoubleToLongFunction: long applyAsLong(double t)
BiFunction<T, U, R>: R apply(T t, U u)
R apply(T t, U u)
"
qui declare deux paramètres ("t" de type "T", "u" de type "U") et retourne une valeur de type "R".
L'implementation doit, typiquement, appliquer une logique autour de la valeur des arguments "t" et "u".BiFunction<Integer, Integer, String> valueOfMax = (a, b) -> "id-".concat(String.valueOf(Math.max(a, b))); System.out.println(valueOfMax.apply(1, 2));
ToIntBiFunction<T, U>: int applyAsInt(T t, U u)
ToLongBiFunction<T, U>: long applyAsLong(T t, U u)
ToDoubleBiFunction<T, U>: double applyAsDouble(T t, U u)
UnaryOperator<T> extends Function<T, T>: T apply(T t)
UnaryOperator<Integer> abs = t -> Math.abs(t); System.out.println(abs.apply(-1));
IntUnaryOperator: int applyAsInt(int t)
LongUnaryOperator: long applyAsLong(long t)
DoubleUnaryOperator: double applyAsDouble(double t)
BinaryOperator<T> extends BiFunction<T, T, T>: T apply(T t, T u)
BinaryOperator<Integer> add = (a, b) -> a + b; System.out.println(add.apply(3, 4));
IntBinaryOperator: int applyAsInt(int t, int u)
LongBinaryOperator: long applyAsLong(long t, long u)
DoubleBinaryOperator: double applyAsDouble(double t, double u)
MyFunctionalInterface foo(FunctionalInterface myFunctionalInterface) { ... }
MyType::MyStaticMethod
public class TestFunctionalInterface { public static String toLowerCase(String value) { return value == null ? "" : value.toLowerCase(); } public static String convert(String value, UnaryOperator<String> myStringConverter) { return myStringConverter.apply(value); } public static void main(String[] args) { final String convertedValue = TestFunctionalInterface.convert("tESt", TestFunctionalInterface::toLowerCase); System.out.println(convertedValue); } }
myInstance::MyInstanceMethod
public class TestFunctionalInterface { public String toUpperCase(String value) { return value == null ? "" : value.toUpperCase(); } public static String convert(String value, UnaryOperator<String> myStringConverter) { return myStringConverter.apply(value); } public static void main(String[] args) { final TestFunctionalInterface testFunctionalInterface = new TestFunctionalInterface(); final String convertedValue = TestFunctionalInterface.convert("tESt", testFunctionalInterface::toUpperCase); System.out.println(convertedValue); } }
MyType::MyInstanceMethod
MyType
" :String::toUpperCase
" (s -> s.toUpperCase) implique que
l’interface fonctionnelle est de type "Function<String, String>
".Function<String, String> toUpperCaseFunction = String::toUpperCase; // s -> s.toUpperCase
TestFunctionalInterface::toUpperCase
" (t -> t.toUpperCase) implique
que l’interface fonctionnelle est de type "Function<TestFunctionalInterface, String>
".Function<TestFunctionalInterface, String> toUpperCaseFunction = TestFunctionalInterface::toUpperCase; // t -> t.toUpperCase
public class TestFunctionalInterface { private String value; public TestFunctionalInterface(String value) { this.value = value; } public String toUpperCase() { return value == null ? "" : value.toUpperCase(); } public static void convert(String value, UnaryOperator<String> myStringConverter) { System.out.println(myStringConverter.apply(value)); } public static void convert(TestFunctionalInterface object, Function<TestFunctionalInterface, String> myFunction) { System.out.println(myFunction.apply(object)); } public static void main(String[] args) { // first example: String::toUpperCase TestFunctionalInterface.convert("hello", String::toUpperCase); // second example: TestFunctionalInterface::toUpperCase TestFunctionalInterface.convert(new TestFunctionalInterface("hello"), TestFunctionalInterface::toUpperCase); } }
MyType::new
public class TestFunctionalInterface { public TestFunctionalInterface(String value) { System.out.println(value); } public static TestFunctionalInterface build(String value, Function<String, TestFunctionalInterface> myFunction) { return myFunction.apply(value); } public static void main(String[] args) { TestFunctionalInterface.build("test", TestFunctionalInterface::new); } }
(t -> t)
public class TestFunctionalInterface { public static String convert(String value, UnaryOperator<String> myStringConverter) { return myStringConverter.apply(value); } public static void main(String[] args) { final String convertedValue = TestFunctionalInterface.convert(" test ", (t -> t == null ? "" : t.trim())); System.out.println(convertedValue); } }