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 :fire:

java.util.function.Predicate

Represents a predicate (boolean-valued function) of one argument.

public interface Predicate<T extends Object> {
  boolean test(T t);
}
java.util.function.Consumer

Represents an operation that accepts a single input argument and returns no result.

public interface Consumer<T extends Object> {
  void accept(T t);
}
java.util.function.Function

Represents a function that accepts one argument and produces a result.

public interface Function<T extends Object, R extends Object> {
  R apply(T t);
}
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.

public interface Supplier<T extends Object> {
  T get();
}
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.

public interface UnaryOperator<T extends Object> extends Function<T, T> {
}

:point_right: Know the above interfaces very well, the inputs as well as the output. :fire:

2.2. Develop code that uses Function interface

public interface Function<T extends Object, R extends Object> {
  R apply(T t);
}

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

public interface Consumer<T extends Object> {
  public void accept(T t);
}

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

public interface Supplier<T extends Object> {
  T get();
}

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

public interface UnaryOperator<T extends Object> extends Function<T, T> {
}

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

public interface Predicate<T extends Object> {
  boolean test(T t);
}

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 :question:

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.

:point_right: You have to know each of the above types for the exam, with their arguments and return types. :fire:

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
IntFunction<String> f1 = (i) -> String.valueOf(i);
System.out.println(f1.apply(100));

IntFunction<String> f1 = String::valueOf;
System.out.println(f1.apply(100));
Reference to a constructor - ClassName::new
Function<char[], String> f1 = String::new;
System.out.println(f1.apply(new char[] {'H', 'i'}));
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.

String::trim // (String str) -> { return str.trim(); }.
BiFunction<String, String, Boolean> f1 = String::equalsIgnoreCase;
System.out.println(f1.apply("Hello", "HELLO"))
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

Integer i = new Integer(1);
Supplier<String> f1 = i::toString;
System.out.println(f1.get());

:bulb: Know when to use which type of method reference.


:memo: Code examples


Next Chapter - Filtering Collections with Lambdas


blog comments powered by Disqus