Primitive Type Specializations of UnaryOperator<T>
The UnaryOperator<T> interface has three primitive type specializations to int, long, and double. The specializations are named PrimUnaryOperator, where Prim is either Int, Long, or Double (Table 13.9). These non-generic unary operators have the functional method applyAsPrim: primitive -> primitive, where primitive is an int, long, or double—the operator takes an argument of a primitive type and returns a result of the same primitive type.
DoubleUnaryOperator celsiusToFahrenheit = celsius -> 1.8 * celsius + 32.0;
System.out.printf(“%.1f Celsius = %.1f Fahrenheit%n”,
25.0, celsiusToFahrenheit.applyAsDouble(25.0));
// 25.0 Celsius = 77.0 Fahrenheit
DoubleUnaryOperator kms = miles -> 1.6 * miles;
System.out.printf(“%.2fmi = %.2fkm%n”, 25.0, kms.applyAsDouble(25.0));
// 25.00mi = 40.00km
The primitive type unary operators define the default methods compose() and andThen() for creating compound primitive type unary operators. The semantics of these default methods are the same as what we saw earlier (p. 715).
IntUnaryOperator incrBy1 = i -> i + 1;
IntUnaryOperator multBy2 = i -> i * 2;
System.out.println(incrBy1.compose(multBy2).applyAsInt(4)); // 9
System.out.println(incrBy1.andThen(multBy2).applyAsInt(4)); // 10
13.11 Extending BiFunction<T,T,T>: BinaryOperator<T>
In Table 13.10, we see that the BinaryOperator<T> interface extends the BiFunction<T, T, T> interface for the special case where the types of the two arguments and the result are the same. It inherits the functional method apply() from the BiFunction<T, T, T> interface, as well as its andThen() method.
BinaryOperator<Double> areaOfRectangle = (length, width) -> length * width;
System.out.printf(“%.2f x %.2f = %.2f%n”,
25.0, 4.0, areaOfRectangle.apply(25.0, 4.0));
// 25.00 x 4.00 = 100.00
Creating compound binary operators is no different from creating compound twoarity functions using the andThen() method, where the parameter function of the method must be a unary operator or a one-arity function.
BinaryOperator<String> concatTwo = (s1, s2) -> s1 + s2;
UnaryOperator<String> postfix1 = s -> s + “nana”;
UnaryOperator<String> postfix2 = s -> s + “s!”;
System.out.println(concatTwo.andThen(postfix1).andThen(postfix2)
.apply(“I am going”, ” ba”)); // I am going bananas!
The two utility methods maxBy() and minBy() can be used to compare two elements according to a given comparator:
String maxStr = BinaryOperator.maxBy(String.CASE_INSENSITIVE_ORDER)
.apply(“aha”, “Madonna”); // Madonna
String minStr = BinaryOperator.minBy(String.CASE_INSENSITIVE_ORDER)
.apply(“aha”, “Madonna”); // aha
Table 13.10 Binary Operators
Functional interface (T, U, and R are type parameters) | Functional method | Default methods unless otherwise indicated |
BinaryOperator<T> extends BiFunction<T,T,T> | apply: (T, T) -> T | andThen(), static maxBy(), static minBy() |
IntBinaryOperator | applyAsInt: (int, int) -> int | – |
LongBinaryOperator | applyAsLong: (long, long) -> long | – |
DoubleBinaryOperator | applyAsDouble: (double, double) -> double | – |
The BinaryOperator<T> interface also provides two utility methods to create binary operators for comparing two elements according to a given comparator:
static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator)
Returns a BinaryOperator which returns the greater of two elements according to the specified comparator.
static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator)
Returns a BinaryOperator which returns the lesser of two elements according to the specified comparator.