Develop code that uses the built-in interfaces included in the java.util.function package, such as Function, Consumer, Supplier, UnaryOperator, Predicate, and Optional APIs, including the primitive and binary variations of the interfaces
Java 8 has some Functional Interfaces already created. They will probably be enough for most scenarios where it is usual to use lambda expressions, so it should not be routine for you to create a new one.
It is critical to understand these examples to master the use of lambda expressions and to understand the next section on method references.
-
Supplieris a functional interface that takes no input parameters but returns a value. Its definition in JDK is as follows:java.util.function.Supplier<T>@FunctionalInterface public interface Supplier<T> { T get(); }
-
A possible implementation for a
Supplieris a current date generator:src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_SupplierExample.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_SupplierExample.java[role=include]
console output2019-07-08The console output will print the current date this code was written.
Note that the lambda expression is simplified, without
{}orreturnbraces. If you have questions about this, go back again to the section on lambda expressions. -
A
Suppliercan be used to provide a costly processing function to be called only if needed:src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_SupplierUseCase.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_SupplierUseCase.java[role=include]
console outputUnder age! Major age! Validation performed at 2019-07-09T00:21:35.488
Note that in this case, the supplier only needed to be called at the second time, avoiding unnecessary execution of the lambda expression.
-
There are
Supplierinterfaces for handling primitive types:BooleanSupplier,IntSupplier,LongSupplierandDoubleSupplier.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_SupplierPrimitive.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_SupplierPrimitive.java[role=include]
The result in the console will be to print the randomly generated primitive
int.
-
Consumeris a functional interface that takes an input parameter, and returns no value. Its definition in JDK is as follows:java.util.function.Supplier<T>@FunctionalInterface public interface Consumer<T> { void accept(T t); }
-
BiConsumeris a functional interface that takes two input parameters, and returns no value. Its definition in JDK is as follows:java.util.function.Consumer<T>@FunctionalInterface public interface BiConsumer<T, U> { void accept(T t, U u); }
-
Possible implementations for
Consumeror` BiConsumer` are functions that print information to the console:src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_ConsumerExample.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_ConsumerExample.java[role=include]
console output2019-07-08 2019-07-08 22:37:39.229
-
There are
Consumerinterfaces to handle primitive types:DoubleConsumer,IntConsumer,LongConsumer,ObjDoubleConsumer,ObjIntConsumerandObjLongConsumer.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_ConsumerPrimitive.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_ConsumerPrimitive.java[role=include]
-
Predicateis a functional interface that takes an input parameter and returns a boolean value. Its definition in JDK is as follows:java.util.function.Predicate<T>@FunctionalInterface public interface Predicate<T> { boolean test(T t); }
-
BiPredicateis a functional interface that takes two input parameters and returns a boolean value. Its definition in JDK is as follows:java.util.function.BiPredicate<T>@FunctionalInterface public interface BiPredicate<T, U> { boolean test(T t, U u); }
-
Possible implementations for
PredicateorBiPredicateare functions that check whether the input value is equal to the raffled value:src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_PredicateExample.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_PredicateExample.java[role=include]
The output on the console is random as it depends on the amount raffled. A possible value would be
falseandtrue. -
There are
Predicateinterfaces for handling primitive types:DoublePredicate,IntPredicateandLongPredicate.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_PredicatePrimitive.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_PredicatePrimitive.java[role=include]
-
Functionis a functional interface that takes an input parameter and returns a value. Its definition in JDK is as follows:java.util.function.Function<T, R>@FunctionalInterface public interface Function<T, R> { R apply(T t); }
-
BiFunctionis a functional interface that takes two input parameters and returns a value. Its definition in JDK is as follows:java.util.function.BiFunction<T>@FunctionalInterface public interface BiFunction<T, U, R> { R apply(T t, U u); }
-
Possible implementations for
FunctionorBiFunctionare functions that multiply the given values:src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_FunctionExample.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_FunctionExample.java[role=include]
console output7.5 30.0
-
There are several
Functioninterfaces for handling primitive types:DoubleFunction,DoubleToIntFunction,DoubleToLongFunction,IntFunction,IntToDoubleFunction,IntToLongFunction,LongFunction,LongToDoubleFunction,LongToIntFunction,ToDoubleBiFunction,ToDoubleFunction,ToIntBiFunction,ToIntFunction,ToLongBiFunction,ToLongFunction.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_FunctionPrimitive.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_FunctionPrimitive.java[role=include]
console output7.5 30.0
-
UnaryOperatoris a functional interface that takes an input parameter and returns a value of the same type as the input. Its definition in JDK is as follows:java.util.function.Function<T, R>@FunctionalInterface public interface UnaryOperator<T> extends Function<T, T> { }
Note that there is no declared abstract method as it only extends the existing
Functioninterface. -
BinaryOperatoris a functional interface that takes two input parameters of the same type, and returns a value of the same type as the inputs. Its definition in JDK is as follows:java.util.function.BiFunction<T>@FunctionalInterface public interface BinaryOperator<T> extends BiFunction<T,T,T> { }
Note that there is no declared abstract method as it only extends the existing
BiFunctioninterface. -
Possible implementations for
UnaryOperatororBinaryOperatorare functions that add a fixed number or add one number to another:src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OperatorExample.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OperatorExample.java[role=include]
console output9 6
-
There are
Operatorinterfaces to handle primitive types:DoubleBinaryOperator,DoubleUnaryOperator,IntBinaryOperator,IntUnaryOperator,LongBinaryOperator,LongUnaryOperator.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OperatorPrimitive.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OperatorPrimitive.java[role=include]
console output9 6
Java 8 has a specific type to represent values that may not have been entered, which is the Optional class. Starting with Java 8, it is often a better option than returning or storing null, as its methods help in many situations.
-
You can create an instance of
Optionalwith value through theofmethod. -
You can create a worthless instance of
Optionalusing theemptymethod. -
You can check if an instance of
Optionalhas a value through theisPresentmethod. -
You can retrieve the value of an instance of
Optionalthrough thegetmethod.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalCreation.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalCreation.java[role=include]
-
It is not possible to call the
ofmethod by passingnullas an argument. For this there is theofNullablemethod.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalNullable.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalNullable.java[role=include]
console outputjava.lang.NullPointerException at java.util.Objects.requireNonNull(Objects.java:203) at java.util.Optional.<init>(Optional.java:96) at java.util.Optional.of(Optional.java:108) at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalNullable.main(BuiltInInterfaces_OptionalNullable.java:11) false
-
With the
ifPresentmethod you can execute a lambda expression only ifOptionalhas value.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalIfPresent.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalIfPresent.java[role=include]
console outputWith Value: value -
You can retrieve a default value if
Optionalis empty. TheorElsemethod returns a value directly, andorElseGetreturns via a lambda expression.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalOrElse.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalOrElse.java[role=include]
console outputdefault value default value value value
TipNote that this is a great case for remembering a benefit of lambda expressions. When using orElseGetthe lambda expression is only executed ifOptionalis empty. In the case of the example, as it is only the return of aString, it makes no difference. However, if it were a heavier operation, you would only actually perform it ifOptionalwas empty. If there was value, the lambda expression would not even be executed, avoiding the processing cost. -
You can also throw an exception if a value is not present in
Optionalusing theorElseThrowmethod.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalOrElseThrow.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalOrElseThrow.java[role=include]
console outputvalue Exception in thread "main" java.lang.RuntimeException at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalOrElseThrow.lambda$main$1(BuiltInInterfaces_OptionalOrElseThrow.java:17) at java.util.Optional.orElseThrow(Optional.java:290) at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalOrElseThrow.main(BuiltInInterfaces_OptionalOrElseThrow.java:17)
-
An exception will be thrown when calling the
getmethod on an emptyOptional.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalGetEmpty.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalGetEmpty.java[role=include]
console outputvalue Exception in thread "main" java.util.NoSuchElementException: No value present at java.util.Optional.get(Optional.java:135) at org.j6toj8.lambda.builtininterfaces.BuiltInInterfaces_OptionalGetEmpty.main(BuiltInInterfaces_OptionalGetEmpty.java:13)
-
There are some classes for dealing with optional value of primitive variables, as they cannot be used with
generics:OptionalInt,OptionalDouble,OptionalLong.src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalPrimitive.javalink:../../../src/org/j6toj8/lambda/builtininterfaces/BuiltInInterfaces_OptionalPrimitive.java[role=include]
console output5
-
Working with Built-In Functional Interfaces
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 173). Wiley. Kindle Edition.
-
Package java.util.function. Java Plataform SE 8.
-
Class Optional<T>. Java Plataform SE 8.