A significant feature introduced for developers in Java 8+ is the language-level support for lambda expressions.
When using lambda expressions, we aim to avoid a feature introduced in Java 5 called autoboxing and unboxing. This occurs when dealing with primitive data types in Java, as the compiler automatically converts a primitive type to its corresponding object (wrapper class) and vice versa, depending on the code.
When implementing lambda expressions, using primitive data types can lead to a performance hit due to the additional processing involved in autoboxing and unboxing.
The java.util.function
provides a set of functional interfaces to play around with primitive data types. Let us see a few:
IntSupplier
@FunctionalInterface
public interface IntSupplier {
/**
* Gets a result.
*
* @return a result
*/ int getAsInt();
}
Implementation:
IntSupplier intSupplier = () -> 18;
int eligibleAgeForVoting = intSupplier.getAsInt();
System.out.println(eligibleAgeForVoting);
IntPredicate
@FunctionalInterface
public interface IntPredicate {
/**
* Evaluates this predicate on the given argument.
*
* @param value the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/ boolean test(int value);
default IntPredicate and(IntPredicate other) {
Objects.requireNonNull(other);
return (value) -> test(value) && other.test(value);
} default IntPredicate negate() {
return (value) -> !test(value);
} default IntPredicate or(IntPredicate other) {
Objects.requireNonNull(other);
return (value) -> test(value) || other.test(value);
}
}
Implementation:
IntPredicate isEligibleToVote = (age) -> age >= 18;
boolean isVoting=isEligibleToVote.test(20);
System.out.println(isVoting);
IntConsumer
@FunctionalInterface
public interface IntConsumer {
/**
* Performs this operation on the given argument.
*
* @param value the input argument
*/ void accept(int value);
default IntConsumer andThen(IntConsumer after) {
Objects.requireNonNull(after);
return (int t) -> { accept(t); after.accept(t); };
}
}
Implementation:
IntConsumer intConsumer =(x)-> System.out.println(x);
intConsumer.accept(25);
DoubleToIntFunction
@FunctionalInterface
public interface DoubleToIntFunction {
/**
* Applies this function to the given argument.
*
* @param value the function argument
* @return the function result
*/ int applyAsInt(double value);
}
Implementation:
DoubleToIntFunction doubleToIntFunction = (someDouble) ->
(int) Math.floor(someDouble);
System.out.println("Value as an int is: " + doubleToIntFunction.applyAsInt(25.5));