Chapter 2. Using Built in Lambda Types
2.1. Describe the built in interfaces included in Java 8 - java.util.function package
New Package:
java.util.function
- Contains a lot of commonly used functional interfaces
java.util.function.Predicate
Represents a predicate (boolean-valued function) of one argument.
java.util.function.Consumer
Represents an operation that accepts a single input argument and returns no result.
java.util.function.Function
Represents a function that accepts one argument and produces a result.
java.util.function.Supplier
Represents a supplier of results. There is no requirement that a new or distinct result be returned each time the supplier is invoked.
java.util.function.UnaryOperator
Represents an operation on a single operand that produces a result of the same type as its operand. This is a specialization of Function for the case where the operand and result are of the same type.
Know the above interfaces very well, the inputs as well as the output.
2.2. Develop code that uses Function interface
Example:
1
2
3
4
5
6
Function<String, Boolean> f = s -> new Boolean(s);
System.out.println(f.apply("TRUE"));
System.out.println(f.apply("true"));
System.out.println(f.apply("Java8"));
System.out.println(f.apply(null));
2.3. Develop code that uses Consumer interface
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class ConsumerDemo {
static class Name {
String name;
Name(String nm) {
name = nm;
}
void setName(String nm) {
name = nm;
}
public String toString() {
return name;
}
}
public static void processList(List<Name> names, Consumer<Name> consumer) {
for (Name n : names) {
consumer.accept(n);
}
}
public static void main(String[] args) {
List<Name> list = Arrays.asList(new Name("a"), new Name("b"), new Name("c"), new Name("d"));
System.out.println(list);
Consumer<Name> capitalize = s -> s.setName(s.name.toUpperCase());
processList(list, capitalize);
System.out.println(list);
}
}
2.4. Develop code that uses Supplier interface
Example: Constructor reference (T::new)
- Much like a method reference, except it is a reference to a constructor instead of a method
- Constructor is not called just referenced.
- On get, the constructor will be called.
1
2
3
Supplier<String> sup = String::new;
System.out.println(sup); // com.jcp8.chapter.two.SupplierDemo$$Lambda$2/990368553@41629346
System.out.println(sup.get()); // ""
2.5. Develop code that uses UnaryOperator interface
Example:
1
2
UnaryOperator<String> uo = s -> "Have a " + s;
System.out.print(uo.apply("good one"));
2.6. Develop code that uses Predicate interface
Example:
1
2
3
4
5
6
7
8
9
10
Predicate<String> boolTest = s -> new Boolean(s).booleanValue();
List<String> strList = Arrays.asList("TRUE", "true", null, "", "false", "TrUe");
processList(strList, boolTest);
private static void processList(List<String> list, Predicate<String> predicate) {
for (String s : list) {
System.out.println(s + " Test pass? " + predicate.test(s));
}
}
2.7. Develop the code that use primitive and binary variations of base interfaces of java.util.function package
A specialized version of the functional interfaces in order to avoid autoboxing operations when the inputs or outputs are primitives.
1
2
3
4
@FunctionalInterface
public interface IntPredicate {
boolean test(int i);
}
Mapping Table
You should know by just the Interface name, what parameter they accept and what they return.
How to remember
Intxx
-> Will take int as an argument and return T or nothing depending on type
ToIntxx
-> Will return int, and take in T as arg if it applies
Predicate<T> |
Consumer<T> |
Function<T, R> |
Supplier<T> |
UnaryOperator<T> |
---|---|---|---|---|
IntPredicate | IntConsumer | IntFunction |
IntSupplier | IntUnaryOperator |
LongPredicate | LongConsumer | LongFunction |
LongSupplier | LongUnaryOperator |
DoublePredicate | DoubleConsumer | DoubleFunction |
DoubleSupplier | DoubleUnaryOperator |
- | - | - | BooleanSupplier | - |
Additional Function<T, R>
IntToDoubleFunction
- Function that accepts an int-valued argument and produces a double-valued result.
IntToLongFunction
- Function that accepts an int-valued argument and produces a long-valued result.
LongToDoubleFunction
- Function that accepts a long-valued argument and produces a double-valued result.
LongToIntFunction
- Function that accepts a long-valued argument and produces an int-valued result.
ToIntFunction<T>
- Function that produces an int-valued result.
ToDoubleFunction<T>
- Function that produces a double-valued result.
ToLongFunction<T>
- Function that produces a long-valued result.
Binary Interfaces - Takes two inputs instead of one
Predicate<T> |
Consumer<T> |
Function<T, R> |
Supplier<T> |
UnaryOperator<T> |
|
---|---|---|---|---|---|
Type | BiPredicate<L, R> | BiConsumer<T, U> | BiFunction<T, U, R> | - | BinaryOperator |
Params | (L, R) -> boolean | (T, U) -> void | (T, U) -> R | - | (T, T) -> T |
Additional Ones
Binary Operators
IntBinaryOperator
- Function operation upon two int-valued operands and producing an int-valued result.
LongBinaryOperator
- Function operation upon two long-valued operands and producing a long-valued result.
DoubleBinaryOperator
- Function operation upon two double-valued operands and producing a double-valued result.
Object Consumers
ObjIntConsumer<T>
- Function operation that accepts an Object-valued and an int-valued argument and returns no result.
ObjLongConsumer<T>
- Function operation that accepts an Object-valued and a long-valued argument and returns no result.
ObjDoubleConsumer<T>
- Function operation that accepts an Object-valued and a double-valued argument and returns no result.
To Primitive Bi-Functions
ToIntBiFunction<T, U>
- Function that accepts two arguments and produces an int-valued result.
ToLongBiFunction<T, U>
- Function that accepts two arguments and produces a long-valued result.
ToDoubleBiFunction<T, U>
- Function that accepts two arguments and produces a double-valued result.
You have to know each of the above types for the exam, with their arguments and return types.
2.8. Develop the code that use method reference; including refactor the code that use Lambda expression to use method references
Method References
- shorthand for lambdas calling only a specific method
- the target reference is placed before the delimiter :: and the name of the method is provided after it.
- String::toUpperCase is a method reference to the method toUpperCase defined in the String class, shorthand for the lambda expression (String s) -> s.toUpperCase();
Four Types:
ContainingClass::staticMethodName - Reference to a static method ContainingObject::instanceMethodName - Reference to an instance method of a particular object ContainingType::methodName - Reference to an instance method of an arbitrary object of a particular type ClassName::new - Reference to a constructor
Reference to a static method - Class::staticMethodName
Reference to a constructor - ClassName::new
Reference to an instance method of an arbitrary object of a particular type - Class::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type refers to a non-static method that is not bound to a receiver.
Reference to an instance method of a particular object - Object::instanceMethodName
Reference to an instance method of a particular object refers to a non-static method that is bound to a receiver.
This kind of method references refers to a situation when you are calling a method in a lambda to an external object that already exists
Know when to use which type of method reference.
Next Chapter - Filtering Collections with Lambdas