Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is specifying parameter types in lambda expressions necessary

Currently, I see no difference in the following Java 8 lambda expressions:

Parameter types specified:

Arrays.sort(strArray, (String s1, String s2) -> s2.length() - s1.length());

Parameter types omitted:

Arrays.sort(strArray, (s1, s2) -> s2.length() - s1.length());

EDIT: In general, what are the pros and cons for specifying parameter types in Java 8 lambda expressions? And when is it necessary to specify?

I've thought of few possible reasons (but I'm sure there are more):

  • additional type safety checks when specified
  • better code readability
like image 817
Ling Zhong Avatar asked Oct 18 '15 04:10

Ling Zhong


3 Answers

There is no difference. It's up to you what the tradeoff is. But frankly, you're better off writing neither of these; instead, import static java.util.Comparator.comparingInt and do Arrays.sort(strArray, comparingInt(String::length)). The first version isn't exactly more type-safe; the second version will infer exactly the same type information and enforce it exactly as much.

like image 115
Louis Wasserman Avatar answered Oct 04 '22 22:10

Louis Wasserman


The lambda function element type is decided by the operate element type.(strArray):

public static <T> void sort(T[] a, Comparator<? super T> c) {
} 

the comparator type is generics and it's decided by your passed parameter type.

The other lambda function is also same:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);
T reduce(T identity, BinaryOperator<T> accumulator);
...

so specify parameter type or not, the compiler already has known what's the parameter type should be.

like image 40
chengpohi Avatar answered Oct 04 '22 21:10

chengpohi


Going off of what @louis-wasserman said in the comments, there is another good example of an instance where you might want to ask that question:

// DOES NOT compile
Arrays.sort(array, Comparator.comparingInts(str -> str.length()).reversed());

// DOES compile
Arrays.sort(array, Comparator.comparingInts((String str) -> str.length()).reversed());

The way I understand it, Comparator.reversed() requires some sort of contract as to how the collection is inherently ordered. Without knowing the type of str it will not know the return type of .length(), thus violating this contract.

like image 34
yiwei Avatar answered Oct 04 '22 21:10

yiwei