util sort new how example java lambda java-8 method-reference

java - sort - Comparator.reversed() no se compila con lambda



lambda java comparator (2)

Esta es una debilidad en el mecanismo de inferencia de tipo del compilador. Para inferir el tipo de u en la lambda, se necesita establecer el tipo de objetivo para la lambda. Esto se consigue de la siguiente manera. userList.sort() espera un argumento de tipo Comparator<User> . En la primera línea, Comparator.comparing() debe devolver Comparator<User> . Esto implica que Comparator.comparing() necesita una Function que tome un argumento de User . Por lo tanto, en la lambda en la primera línea, debes ser del tipo User y todo funciona.

En la segunda y tercera líneas, la tipificación del objetivo se ve interrumpida por la presencia de la llamada a reversed() . No estoy del todo seguro por qué; tanto el receptor como el tipo de retorno de reversed() son Comparator<T> por lo que parece que el tipo de destino debe propagarse nuevamente al receptor, pero no es así. (Como dije, es una debilidad).

En la segunda línea, la referencia del método proporciona información de tipo adicional que llena este espacio. Esta información está ausente de la tercera línea, por lo que el compilador infiere que u es un Object (la inferencia alternativa de último recurso), que falla.

Obviamente, si puedes usar una referencia de método, hazlo y funcionará. A veces no puede usar una referencia de método, por ejemplo, si desea pasar un parámetro adicional, por lo que debe usar una expresión lambda. En ese caso, debe proporcionar un tipo de parámetro explícito en el lambda:

userList.sort(Comparator.comparing((User u) -> u.getName()).reversed());

Es posible que el compilador se mejore para cubrir este caso en una versión futura.

Tengo una lista con algunos objetos de Usuario y estoy tratando de ordenar la lista, pero solo funciona usando la referencia de método, con la expresión lambda el compilador da un error:

List<User> userList = Arrays.asList(u1, u2, u3); userList.sort(Comparator.comparing(u -> u.getName())); // works userList.sort(Comparator.comparing(User::getName).reversed()); // works userList.sort(Comparator.comparing(u -> u.getName()).reversed()); // Compiler error

Error:

com/java8/collectionapi/CollectionTest.java:35: error: cannot find symbol userList.sort(Comparator.comparing(u -> u.getName()).reversed()); ^ symbol: method getName() location: variable u of type Object 1 error


Puede evitar esta limitación utilizando el Comparator.comparing dos argumentos con Comparator.reverseOrder() como el segundo argumento:

users.sort(comparing(User::getName, reverseOrder()));