Java Reference
In-Depth Information
Listing 2-16. Using Operator Types to Capture Familiar Lambdas
UnaryOperator<String> upperCase = str -> str.toUpperCase();
BinaryOperator<String> concat = (left,right) -> left + right;
Lambdas as Predicates
This topic opened up with a story about the usefulness of predicate types. Java has implemented predicates
as a special case of the Function functional interface: specifically, one that takes any type and returns a
boolean . This is an extremely common functional type that simply returns true or false and that is used any
time your functional program has a conditional branch, a filter, or a guard. We demonstrate a basic “not null
or empty” check for a String in Listing 2-17.
Listing 2-17. Predicate Lambda Checking if a String Is Null or Empty
Predicate<String> notNullOrEmpty = s -> s != null && s.length() > 0;
Lambdas with Primitive Arguments
In Listing 2-8, we saw a Supplier that returned a given integer value, 1 . However, that value was returned
as an object extending Number , not as the primitive value. This is an example of a “boxed integer,” and the
implicit conversion that just happened is called “autoboxing.” Many developers have an allergy to boxing
primitive values, even though the real performance impact of boxing is largely negated through compiler
optimizations, standard library performance tricks, and Java's excellent garbage collector. However, there are
still cases when the performance cost of autoboxing is significant; and if you are dealing with a lot of integer
values, you might as well avoid the autoboxing. For those cases, you can create lambdas that use primitives.
There are primitive functional interfaces for the double , int , and long primitive types. There are also
functional interfaces that take one of those primitive types and produce another of those primitive types,
such as DoubleToIntFunction . Java provides primitive versions of most of the functional interfaces. The most
notable missing entry in this list is ObjIntBifunction : I don't know why Java didn't provide this interface.
While we only take a look at the int interfaces in Listing 2-18, rest assured, there are corresponding
versions of each of these interfaces for the double and long primitive types, too. Just replace "Int" with
"Double" in the class name, and you have the corresponding functional type for the double type.
Listing 2-18. Predicate Lambda Checking if a String Is Null or Empty
IntFunction<String> intToString = i -> Integer.toString(i);
ToIntFunction<String> parseInt = str -> Integer.valueOf(str);
IntPredicate isEven = i -> i % 2 == 0;
ToIntBiFunction<String,String> maxLength =
(left,right) -> Math.max(left.length(), right.length());
IntConsumer printInt = i -> System.out.println(Integer.toString(i));
ObjIntConsumer<String> printParsedIntWithRadix =
(str,radix) -> System.out.println(Integer.parseInt(str,radix));
IntSupplier randomInt = () -> new Random().nextInt();
IntUnaryOperator negateInt = i -> -1 * i;
IntBinaryOperator multiplyInt = (x,y) -> x*y;
IntToDoubleFunction intAsDouble = i -> Integer.valueOf(i).doubleValue();
DoubleToIntFunction doubleAsInt = d -> Double.valueOf(d).intValue();
IntToLongFunction intAsLong = i -> Integer.valueOf(i).longValue();
LongToIntFunction longAsInt = x -> Long.valueOf(x).intValue();
 
Search WWH ::




Custom Search