2.7.  Develop code that uses the primitive and binary variations of the base interfaces of the java.util.function package

[Note]
  • blah

Every Java type is either a reference type (for example, String, Integer, Object, List) or a primitive type (for example, int, double, byte, char). But generic parameters (for example, the T in Consumer<T>) can be bound only to reference types. This is due to how generics are internally implemented.

As a result, in Java there is a mechanism to convert a primitive type into a corresponding reference type. This mechanism is called boxing. The opposite approach (that is, converting a reference type into a corresponding primitive type) is called unboxing. Java also has an autoboxing mechanism to facilitate the task for programmers: boxing and unboxing operations are done automatically. For example, this is why the following code is valid (a double gets boxed to a Double):


List<Double> list = new ArrayList<>();
list.add(12.34);
list.add(56.78);

					

But this comes with a performance cost. Boxed values are essentially a wrapper around primitive types and are stored on the heap. Therefore, boxed values use more memory and require additional memory lookups to fetch the wrapped primitive value. Java 8 brings a specialized version of the functional interfaces in order to avoid autoboxing operations when the inputs or outputs are primitives. For example, in the following code, using an IntPredicate avoids a boxing operation of the value 1974:


package java.util.function;

@FunctionalInterface
public interface IntPredicate {

    public boolean test(int i);

    ...
}


					


IntPredicate ip = i -> i == 1974;
ip.test(1974);

					

whereas using a Predicate<Integer> would box the argument 1974 to an Integer object:


package java.util.function;

@FunctionalInterface
public interface Predicate<T extends Object> {

    public boolean test(T t);

    ...
}


					


Predicate<Integer> p = i -> i == 1974;
p.test(1974);

					

In general, the names of functional interfaces that have a specialization for the input type parameter are preceded by the appropriate primitive type, for example, DoublePredicate, IntConsumer, LongBinaryOperator, IntFunction, and so on.

The Function interface has also variants for the output type parameter: ToIntFunction<T>, ToDoubleFunction<T>, and so on.

Table 2.1.  Common functional interfaces in Java 8

Functional interfaceFunction descriptorPrimitive specializations

Predicate<T>

T -> boolean

IntPredicate - Predicate of one int-valued argument.

LongPredicate - Predicate of one long-valued argument.

DoublePredicate - Predicate of one double-valued argument.

Consumer<T>

T -> void

IntConsumer - Function operation that accepts a single int-valued argument and returns no result.

LongConsumer - Function operation that accepts a single long-valued argument and returns no result.

DoubleConsumer - Function operation that accepts a single double-valued argument and returns no result.

Function<T, R>

T -> R

IntFunction<R> - Function that accepts an int-valued argument and produces a result.

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.

LongFunction<R> - Function that accepts a long-valued argument and produces a 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.

DoubleFunction<R> - Function that accepts a double-valued argument and produces a 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.

DoubleToIntFunction; - Function that accepts a double-valued argument and produces an int-valued result.

DoubleToLongFunction - Function that accepts a double-valued argument and produces a long-valued result.

Supplier<T>

() -> T

BooleanSupplier - Supplier of boolean-valued results.

IntSupplier - Supplier of int-valued results.

LongSupplier - Supplier of long-valued results.

DoubleSupplier - Supplier of double-valued results.

UnaryOperator<T>

T -> T

IntUnaryOperator - Function operation on a single int-valued operand that produces an int-valued result.

LongUnaryOperator - Function operation on a single long-valued operand that produces a long-valued result.

DoubleUnaryOperator - Function operation on a single double-valued operand that produces a double-valued result.

BinaryOperator<T>

(T, T) -> T

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.

BiPredicate<L, R>

(L, R) -> boolean

none

BiConsumer<T, U>

(T, U) -> void

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.

BiFunction<T, U, R>

(T, U) -> R

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.


Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Exam 1Z0-810: Upgrade to Java SE 8 Programmer Quiz