13.7 Consumers
The Consumer<T> functional interface represents a consumer of values. From Table 13.6, we see that its functional method accept() has the type T -> void—that is, it takes an argument of type T and returns no value (void). Typically, it performs some operation on its argument object.
Table 13.6 shows all the consumer functional interfaces, together with their functional method accept() and any default methods that are provided by the interface. There are three primitive type one-arity specializations of the Consumer<T> functional interface, recognized by their characteristic prefixes. The generic two-arity specialization (BiConsumer<T,U>) also has three two-arity primitive type specializations. Only the one-arity consumers and the two-arity generic consumer define the default method andThen().
Table 13.6 Consumers
Functional interface (T, U, and R are type parameters) | Functional method | Default methods |
Consumer<T> | accept: T -> void | andThen() |
IntConsumer | accept: int -> void | andThen() |
LongConsumer | accept: long -> void | andThen() |
DoubleConsumer | accept: double -> void | andThen() |
BiConsumer<T, U> | accept: (T, U) -> void | andThen() |
ObjIntConsumer<T> | accept: (T, int) -> void | – |
ObjLongConsumer<T> | accept: (T, long) -> void | – |
ObjDoubleConsumer<T> | accept: (T, double) -> void | – |
Generally, a consumer performs an operation on its argument object, but does not return a value. The formatter below prints a double value with two decimal places. The type of the lambda expression is Double -> void, and the lambda expression is executed when the method accept() is invoked.
Consumer<Double> formatter = d -> System.out.printf(“Value: %.2f%n”, d);
formatter.accept(3.145); // Value: 3.15
In the code below, the resizeSB consumer resizes a StringBuilder to length 4—a more flexible resizer is presented a little later. The reverseSb consumer reverses the contents of a StringBuilder. The printSB consumer prints a StringBuilder. In each case, the type of the lambda expression is StringBuilder -> void.
StringBuilder sb1 = new StringBuilder(“Banana”);
Consumer<StringBuilder> resizeSB = sb -> sb.setLength(4);
resizeSB.accept(sb1); // Bana
Consumer<StringBuilder> reverseSB = sb -> sb.reverse();
reverseSB.accept(sb1); // anaB
Consumer<StringBuilder> printSB
= sb -> System.out.println(“StringBuilder: ” + sb);
printSB.accept(sb1); // StringBuilder: anaB
The ArrayList.forEach() method requires a consumer that is applied to each element of the list—that is, the method call consumer.accept(element) is executed on each element in the list. The consumer below prints an element of the list words in lowercase.
// [Otto, ADA, Alya, Bob, HannaH, Java]
words.forEach(s -> System.out.print(s.toLowerCase() + ” “));
// otto ada alya bob hannah java
The code below implements the Consumer<String> interface using an anonymous class which is passed as an argument to the ArrayList.forEach() method:
// [Otto, ADA, Alya, Bob, HannaH, Java]
words.forEach(new Consumer<String>() {
public void accept(String s) {
System.out.print(s.toLowerCase() + ” “);
}
});
// otto ada alya bob hannah java
The following consumer prints each element of the list words that has an even length:
// [Otto, ADA, Alya, Bob, HannaH, Java]
words.forEach(s -> {if (s.length() % 2 == 0) System.out.print(s + ” “);});
// Otto Alya HannaH Java