any interface that has exactly one abstract method is called …
a functional interface
abstract method
methods from e.g. an interface that has a signature but not an implementation (the class that implements the interface will define the method with its own implementation - don’t forget annotation @Override)
is List a functional interface?
no - it does not have only one method, it has many methods. A functional interface must have one method.
can a developer create a new functional interface?
yes they can. Java libraries also provide many functional interfaces - they are called “the standard Java functional interfaces”. (we cover four in ATA)
What are the four functional interfaces from Java that are covered in ATA?
Function, Supplier, Consumer, Predicate
To implement an interface the standard way…
lambda expressions provide…
a quick and easy way to implement a functional interface without expliciitly defining a class or even a formal method declaration.
syntax of a lambda expression
argument -> method implementation
or
(arg1, arg2) -> method implementation
or
() -> method implementation
or
(arg(s)) -> {
mulit-line method
implementation
}
Because each functional interface contains exactly one abstract method, lambda expressions allow us to implement only that one method (following the arrow) to satisfy the interface. We don't need to creat a class, and since the interface has only one method, we don't even need to name it!three parts to lambda expression
Function interface
public interface Function {
R apply(T t);
}
takes an input object, returns an output objectwhy don’t we need to name the method we call in a lambda expression?
the lamda “operator” -> automatically calls the ONE method in the interface, that one method is defined on the right of the -> operator
Supplier interface
public interface Supplier {
T get();
}
no input, returns an outputSupplier examples
List participants = {"ace", "queen", "diamond"}
Random random = new Random();
Supplier randomIndex =
() -> random.nextInt(participants.size());
------
public void callOnParticipant(Supplier index) {
String person = participants.get(indexChooser.get());
System.out.println("Hello " + person);
}Supplier interface notes
note on keyword ‘return’ in lambda expressions
if you drop the curly braces from your one-line method implementation, and the functional interface that your lambda expression is implementing has a return value, you drop the keyword return. (most common usage of a lambda)
method reference
if your lambda expression simply calls a method, this syntax is a way to “compactify” it:
long form: key -> method(key) or item -> item==null etc
I. Reference to an instance method of a particular object: containingObject::instanceMethodName
e.g.: recommendationsServiceClient::getBookRecs
(from .build(CacheLoader.from(^^)
II. Reference to an instance method of an arbitrary object of a particular type: ContainingType::methodName
e.g.: list.removeIf(String::isEmpty)
III. Reference to a static method:
ContainingClass::staticMethodName
e.g.: list.removeIf(StringUtils::isBlank)
e.g.: PublishingConverter::toPublishRecord
Consumer interface
public interface Consumer {
void accept;
}
when are consumers used?
Consumers are commonly used when:
example of Consumer
List names = fetchNames();
names.forEach(name -> System.out.println(“name: “ + name);
(note: forEach(Consumer action) is a List method)
fancier:
Consumer fancyLambda = myString -> System.out.println(“Hello there “ + myString “, how are you today?”);
names.forEach(fancyLambda);
Predicate interface
public interface Predicate {
boolean test(T t);
}what is Predicate used for?
Predicate is often used to filter (in or out) elements from a data structure, or to conditionally perform some operation on elements of a data structure.
A Predicate performs a test on an objects, and specifies whether it meets a certain condition or not.
examples of Predicate
value -> value == null;
list. removeIf(value -> value == null);
(note: removeIf(Predicate filter) is a list method, it removes all elements of the collection that satisfy the given predicate. this method returns true if any element was removed.)
remove all palindromes from a list
List noPalindrome = fetchWords;
noPalidrome.removeIf(text -> {
String reverse = new StringBuffer(text).reverse.toString();
return text.equals(reverse);
});note:
1. with only one input, don’t need parentheis
2. the Predicate’s test(T t) method is inside the {} since multiple lines
3. the removeIf has regular parentheses () and end with ;
4. needs return since multiline (single line skips explicit return statement, it’s implied)
- ->( t -> { blabla; return boolean} );
If the input “satisfies the predicate” - means the test(input) returns true - the item is removed from the list.
**removeIf is a Collections method, which List inherits, so any collection can do this
can a Predicate have two inputs
no - the signature test(T t) accounts for one input