![]() | |
|
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 8.1. Common functional interfaces in Java 8
Functional interface | Function descriptor | Primitive specializations |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
none |
|
|
|
|
|
|
![]() ![]() ![]() |