Composing Consumers
The method andThen() can be used to chain together consumers to compose compound consumers. The three consumers used earlier to resize, reverse, and print a StringBuilder can be chained together as seen here:
resizeSB.andThen(reverseSB)
.andThen(printSB).accept(new StringBuilder(“Banana”)); // StringBuilder: anaB
The constituent consumers are executed one after the other from left to right. Note that the reference to the StringBuilder instance passed to the accept() method is also passed to each constituent consumer.
default Consumer<T> andThen(Consumer<? super T> after)
Returns a composed Consumer that evaluates this operation first followed by the specified after operation.
Any exception thrown during the evaluation of either operation aborts the evaluation of the composed operation and the exception is conveyed to the caller.
Primitive Type Specializations of Consumer<T>
From Table 13.6, we see that the non-generic functional interfaces IntConsumer, LongConsumer, and DoubleConsumer define the functional method accept() that takes an int, a long, or a double value as an argument, respectively, but does not return a value (void). The primitive type versions avoid the overhead of boxing and unboxing of primitive values. They are not subinterfaces of the Consumer<T> interface, and they all provide the andThen() method to compose compound primitive type consumers.
The two IntConsumers below print the square root and the square of their argument, respectively. They are chained by the andThen() method that requires an IntConsumer.
IntConsumer sqrt = i -> System.out.printf(“%.2f%n”, Math.sqrt(i));
IntConsumer sqr = i -> System.out.printf(“%d%n”, i * i);
sqrt.andThen(sqr).accept(15); // 3.87
// 225
Two-Arity Specialization of Consumer<T>: BiConsumer<T, U>
The BiConsumer<T, U> interface is a two-arity specialization of the Consumer<T> interface. From Table 13.6, we see that its functional method accept() has the type (T, U) -> void—that is, it takes two arguments of type T and type U, and does not return a value (void). The BiConsumer<T, U> interface provides the andThen() method to create compound two-arity consumers.
The following code illustrates defining and using two-arity consumers.
BiConsumer<String, Double> formatPrinter
= (format, obj) -> System.out.printf(format, obj);
formatPrinter.accept(“Math.PI:|%10.3f|%n”, Math.PI); // Math.PI:| 3.142|
The java.util.Map.forEach() method requires a two-arity consumer that is applied to each entry (key, value) in the map—that is, the method call biconsumer.accept(key, value) is executed for each entry in the map. The two-arity consumer below formats and prints all entries in the map given by the reference strLenMap. The key in this map is of type String and the value is of type Integer— that is, HashMap<String, Integer>. The value is the length of the key string.
// Map entries (default format): {Java=4, Bob=3, Otto=4, HannaH=6, Alya=4, ADA=3}
strLenMap.forEach((key, value) -> System.out.printf(“(%s:%d) “, key, value));
// (Java:4) (Bob:3) (Otto:4) (HannaH:6) (Alya:4) (ADA:3)