primitive |
Having studied Collections Streams and Filters and Functional interfaces: Supplier, Consumer, Predicate, Function, now its time to study their corresponding primitive counter parts.
OCPJP is fond of having questions like this:
Which answer can replace the __ in the following code?
int x = 10;
__ f = x -> x + 1;
f.applyAsInt(10);
A. BinaryOperator
B. UnaryOperator
C. IntUnaryOperator
D. DoubleToIntFunction
E. LongToIntFunction
In order to be able to select C, you need to remember the primitive Functional Interfaces as well as their abstract interface method names.
According to java.util.function package's class list.
- Type parameters of functional interfaces can be specialized to primitives with additional type prefixes. To specialize the return type for a type that has both generic return type and generic arguments, we prefix
ToXxx
, as inToIntFunction
. Otherwise, type arguments are specialized left-to-right, as inDoubleConsumer
orObjIntConsumer
. (The type prefixObj
is used to indicate that we don't want to specialize this parameter, but want to move on to the next parameter, as inObjIntConsumer
.) These schemes can be combined, as inIntToDoubleFunction
.
Let's try to memorize these functional interfaces for primitives.
BooleanSupplier.getAsBoolean
OCPJP>cat BooleanSupplierDemo.java
import java.util.function.*;
public class BooleanSupplierDemo {
public static void main(String...args) {
BooleanSupplier booleanSupplier = () -> true;
boolean truth = booleanSupplier.getAsBoolean();
System.out.println(truth);
booleanSupplier = () -> Math.random() > .3;
System.out.println(booleanSupplier.getAsBoolean());
}
}
OCPJP>javac BooleanSupplierDemo.java
OCPJP>java BooleanSupplierDemo
true
true
OCPJP>java BooleanSupplierDemo
true
true
OCPJP>java BooleanSupplierDemo
true
false
OCPJP>
Supplier<T>, DoubleSupplier, IntSupplier, LongSupplier, BooleanSupplier
getXXX
OCPJP>cat SupplierDemo.java
import java.util.function.*;
public class SupplierDemo {
public static void main(String[] args) {
Supplier<String> supplier = () -> "whatever";
System.out.println("Supplier<T> get(): " + supplier.get());
DoubleSupplier doubleSupplier = () -> .333;
System.out.println("DoubleSupplier getAsDouble(): " + doubleSupplier.getAsDouble());
IntSupplier intSupplier = () -> 10;
System.out.println("IntSupplier getAsInt(): " + intSupplier.getAsInt());
LongSupplier longSupplier = () -> 100_000L;
System.out.println("LongSupplier getAsLong(): " + longSupplier.getAsLong());
BooleanSupplier booleanSupplier = () -> true;
System.out.println("BooleanSupplier getAsBoolean(): " + booleanSupplier.getAsBoolean());
}
}
OCPJP>javac SupplierDemo.java
OCPJP>java SupplierDemo
Supplier<T> get(): whatever
DoubleSupplier getAsDouble(): 0.333
IntSupplier getAsInt(): 10
LongSupplier getAsLong(): 100000
BooleanSupplier getAsBoolean(): true
OCPJP>
Consumer<T>, DoubleConsumer, IntConsumer, LongConsumer, BooleanConsumer, ObjDoubleConsumer, ObjIntConsumer, ObjLongConsumer
accept
OCPJP>cat ConsumerDemo.java
import java.util.function.*;
public class ConsumerDemo {
public static void main(String... args) {
Consumer<String> consumer = i -> System.out.println("Consumer<T> accept(T t): " + i);
consumer.accept("whatever");
DoubleConsumer doubleConsumer = i -> System.out.println("DoubleConsumer accept(double d): " + i);
doubleConsumer.accept(.999);
IntConsumer intConsumer = i -> System.out.println("IntConsumer accept(int i): " + i);
intConsumer.accept(100);
LongConsumer longConsumer = i -> System.out.println("LongConsumer accept(long l): " + i);
longConsumer.accept(100_000);
// no BooleanConsumer class
ObjDoubleConsumer<String> objDoubleConsumer = (i, j)
-> System.out.println("ObjDoubleConsumer<T> accept(T t, double d): " + i + j);
objDoubleConsumer.accept("whatever", 10.00);
ObjIntConsumer<Double> objIntConsumer = (i, j)
-> System.out.println("ObjIntConsumer<T> accept(T t, int i): " + i + j);
objIntConsumer.accept(10.01, 5);
ObjLongConsumer<Long> objLongConsumer = (i, j)
-> System.out.println("ObjLongConsumer<T> accept(T t, long l): " + Math.max(i, j));
objLongConsumer.accept(1000L, 2000L);
}
}
OCPJP>javac ConsumerDemo.java
OCPJP>java ConsumerDemo
Consumer<T> accept(T t): whatever
DoubleConsumer accept(double d): 0.999
IntConsumer accept(int i): 100
LongConsumer accept(long l): 100000
ObjDoubleConsumer<T> accept(T t, double d): whatever10.0
ObjIntConsumer<T> accept(T t, int i): 10.015
ObjLongConsumer<T> accept(T t, long l): 2000
OCPJP>
Predicate<T>, DoublePredicate, IntPredicate, LongPredicate
test(xxx t)
OCPJP>cat PredicateDemo.java
import java.util.function.*;
public class PredicateDemo {
public static void main(String...args) {
Predicate<String> predicate = s -> s.equals("whatever");
System.out.println("Predicate<T> test(T t): " + predicate.test("whatever"));
DoublePredicate doublePredicate = i -> i > .5;
System.out.println("DoublePredicate test(double d): " + doublePredicate.test(.89));
IntPredicate intPredicate = i -> i > 100;
System.out.println("IntPredicate test(int i): " + intPredicate.test(59));
LongPredicate longPredicate = i -> i == 10_000L;
System.out.println("LongPredicate test(long l): " + longPredicate.test(20_000));
}
}
OCPJP>javac PredicateDemo.java
OCPJP>java PredicateDemo
Predicate<T> test(T t): true
DoublePredicate test(double d): true
IntPredicate test(int i): false
LongPredicate test(long l): false
OCPJP>
Function<T, R>, DoubleFunction<R>, IntFunction<R>, LongFunction<R>
apply(xxxx t)
OCPJP>cat FunctionDemo.java
import java.util.function.*;
public class FunctionDemo {
public static void main(String[] args) {
Function<String, String> function = i -> i + " anytype";
System.out.println("Function<T, R> apply(T t): " + function.apply("whatever"));
DoubleFunction<Double> doubleFunction = Math::acos;
System.out.println("DoubleFunction<R> apply(double d): " + doubleFunction.apply(1.45));
IntFunction<String> intFunction = i -> i + " return whatever";
System.out.println("IntFunction<R> apply(int i): " + intFunction.apply(10));
LongFunction<Long> longFunction = Math::incrementExact;
System.out.println("LongFunction<R> apply(long l): " + longFunction.apply(10_000L));
}
}
OCPJP>javac FunctionDemo.java
OCPJP>java FunctionDemo
Function<T, R> apply(T t): whatever anytype
DoubleFunction<R> apply(double d): NaN
IntFunction<R> apply(int i): 10 return whatever
LongFunction<R> apply(long l): 10001
OCPJP>
UnaryOperator<T>, DoubleUnaryOperator, IntUnaryOperator, LongUnaryOperator
applyAsxxx(xxx t)
OCPJP>cat UnaryOperatorDemo.java
import java.util.function.*;
public class UnaryOperatorDemo {
public static void main(String... args) {
UnaryOperator<String> unaryOperator = i -> i + i;
System.out.println("UnaryOperator<T> apply(T t): " + unaryOperator.apply("whatever"));
DoubleUnaryOperator doubleUnaryOperator = Math::sqrt;
System.out.println("DoubleUnaryOperator applyAsDouble(double d): " + doubleUnaryOperator.applyAsDouble(10));
IntUnaryOperator intUnaryOperator = Math::abs;
System.out.println("IntUnaryOperator applyAsInt(int i): " + intUnaryOperator.applyAsInt(-10));
LongUnaryOperator longUnaryOperator = i -> i / 2;
System.out.println("LongUnaryOperator applyAsLong(long l): " + longUnaryOperator.applyAsLong(10_000));
}
}
OCPJP>javac UnaryOperatorDemo.java
OCPJP>java UnaryOperatorDemo
UnaryOperator<T> apply(T t): whateverwhatever
DoubleUnaryOperator applyAsDouble(double d): 3.1622776601683795
IntUnaryOperator applyAsInt(int i): 10
LongUnaryOperator applyAsLong(long l): 5000
OCPJP>
BinaryOperator<T>, DoubleBinaryOperator, IntBinaryOperator, LongBinaryOperator
applyxxxx(xxx t)
OCPJP>cat BinaryOperatorDemo.java
import java.util.function.*;
public class BinaryOperatorDemo {
public static void main(String[] args) {
BinaryOperator<String> binaryOperator = (i, j) -> i + j;
System.out.println("BinaryOperator<T> apply(T t): " + binaryOperator.apply("whatever", "whateversametype"));
DoubleBinaryOperator doubleBinaryOperator = Math::pow;
System.out.println("DoubleBinaryOperator applyAsDouble(double d): " + doubleBinaryOperator.applyAsDouble(.2, .3));
IntBinaryOperator intBinaryOperator = Math::min;
System.out.println("IntBinaryOperator applyAsInt(int i): " + intBinaryOperator.applyAsInt(10, 20));
LongBinaryOperator longBinaryOperator = Math::max;
System.out.println("LongBinaryOperator applyAsLong(long l): " + longBinaryOperator.applyAsLong(10_1000L, 13_000L));
}
}
OCPJP>javac BinaryOperatorDemo.java
OCPJP>java BinaryOperatorDemo
BinaryOperator<T> apply(T t): whateverwhateversametype
DoubleBinaryOperator applyAsDouble(double d): 0.6170338627200097
IntBinaryOperator applyAsInt(int i): 10
LongBinaryOperator applyAsLong(long l): 101000
OCPJP>
ToDoubleFunction<T>, ToIntFunction<T>, ToLongFunction<T>, ToDoubleBiFunction<T, U>, ToIntBiFunction<T, U>, ToLongBiFunction<T, U>, DoubleToIntFunction, DoubleToLongFunction, IntToDoubleFunction, IntToLongFunction, LongToDoubleFunction, LongToIntFunction.
OCPJP>cat TypeToTypeFunctionDemo.java
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.function.*;
public class TypeToTypeFunctionDemo {
public static void main(String... args) {
ToDoubleFunction<String> toDoubleFuncion = i -> 0.999;
System.out.println("ToDoubleFunction<T> applyAsDouble(T t): " + toDoubleFuncion.applyAsDouble("whatever"));
ToIntFunction<String> toIntFunction = String::length;
System.out.println("ToIntFunction<T> applyAsInt(T t): " + toIntFunction.applyAsInt("whateverString"));
ToLongFunction<LocalDateTime> toLongFunction = i -> i.toEpochSecond(ZoneOffset.of("+10"));
System.out.println("ToLongFunction<T t> applyAsLong<T t>: " + toLongFunction.applyAsLong(LocalDateTime.now()));
ToDoubleBiFunction<String, String> toDoubleBiFunction = (i, j) -> i.length() + j.length();
System.out.println("ToDoubleBiFunction<T t, U u> applyAsDouble(T t, U u): " + toDoubleBiFunction.applyAsDouble("whateverStrign", "whateveranotherString"));
ToIntBiFunction<String, Integer> toIntBiFunction = (i, j) -> i.length() + j;
System.out.println("ToIntBiFunction<T t, U u> applyAsInt(T t, U u): " + toIntBiFunction.applyAsInt("whateverStringObject", 10));
ToLongBiFunction<LocalDateTime, String> toLongBiFunction = (i, j) -> i.toEpochSecond(ZoneOffset.of("+10")) + j.length();
System.out.println("ToLongBiFunction<T t, U u> applyAsLong(T t, U u): " + toLongBiFunction.applyAsLong(LocalDateTime.now(), "a String"));
DoubleToIntFunction doubleToIntFunction = i -> Math.getExponent(i);
System.out.println("DoubleToIntFunction applyAsInt(double d): " + doubleToIntFunction.applyAsInt(3.333));
DoubleToLongFunction doubleToLongFunction = i -> 10L;
System.out.println("DoubleToLongFunction applyAsLong(double d): " + doubleToLongFunction.applyAsLong(.22));
IntToDoubleFunction intToDoubleFunction = i -> Math.exp(i);
System.out.println("IntToDoubleFunction applyAsDouble(int i): " + intToDoubleFunction.applyAsDouble(2));
IntToLongFunction intToLongFunction = i -> i;
System.out.println("IntToLongFunction applyAsLong(int i): " + intToLongFunction.applyAsLong(10));
LongToDoubleFunction longToDoubleFunction = i -> i/3;
System.out.println("LongToDoubleFunction applyAsDouble(long l): " + longToDoubleFunction.applyAsDouble(5L));
LongToIntFunction longToIntFunction = i -> (int)i << 2;
System.out.println("LongToIntFunction applyAsInt(long l): " + longToIntFunction.applyAsInt(10_000L));
}
}
OCPJP>javac TypeToTypeFunctionDemo.java
OCPJP>java TypeToTypeFunctionDemo
ToDoubleFunction<T> applyAsDouble(T t): 0.999
ToIntFunction<T> applyAsInt(T t): 14
ToLongFunction<T t> applyAsLong<T t>: 1506131924
ToDoubleBiFunction<T t, U u> applyAsDouble(T t, U u): 35.0
ToIntBiFunction<T t, U u> applyAsInt(T t, U u): 30
ToLongBiFunction<T t, U u> applyAsLong(T t, U u): 1506131932
DoubleToIntFunction applyAsInt(double d): 1
DoubleToLongFunction applyAsLong(double d): 10
IntToDoubleFunction applyAsDouble(int i): 7.38905609893065
IntToLongFunction applyAsLong(int i): 10
LongToDoubleFunction applyAsDouble(long l): 1.0
LongToIntFunction applyAsInt(long l): 40000
OCPJP>