Collectors.maxBy (Comparator.naturalOrder ()) non viene compilato sebbene sia dedotto Long

Aug 21 2020

Non riesco a compilare la seguente parte di codice (prova su onlinegdb ):

List<Container<Dto>> list = Arrays.asList(
                new Container<>(new Dto("A"), 10L),
                new Container<>(new Dto("A"), 30L),
                new Container<>(new Dto("B"), 30L));

Map<String, Optional<Long>> mapWrong = list.stream()
    .collect(Collectors.groupingBy(
        c -> c.getOutput().getType(),
        Collectors.mapping(
            Container::getDifference, 
            Collectors.maxBy(Comparator.naturalOrder()))));     // DOESN'T WORK WITH THIS 

tipi incompatibili: impossibile dedurre variabili di tipo T, U, A, R, cattura n. 2 di?, T, T (argomento non corrispondente; metodo di riferimento del metodo non valido getDifference nella classe Il contenitore non può essere applicato a determinati tipi richiesti: nessun argomento trovato: java.lang Motivo oggetto: gli elenchi di argomenti effettivi e formali differiscono in lunghezza)

Non ho idea di cosa causi l'errore di compilazione. Il Collectors.mappingmapping di un oggetto a un nuovo valore e poiché Container::getDifferencerestituisce longe lo stesso tipo dovrebbe essere dedotto Collectors.maxBye il codice dovrebbe essere compilato.

Sorprendentemente, quando sostituisco il Comparator.naturalOrder()con Comparator.comparingLong(l -> l), allora funziona.

Map<String, Optional<Long>> mapCorrect = list.stream()
    .collect(Collectors.groupingBy(
        c -> c.getOutput().getType(),
        Collectors.mapping(
            Container::getDifference, 
            Collectors.maxBy(Comparator.comparingLong(l -> l)))));   // A CHANGE TO FIX IT

Gli oggetti utilizzati (inclusi il costruttore di tutti gli argomenti e i getter):

public class Container<T> {
    T output;
    long difference;
}
public class Dto {
    String type;
}

Nota che questo è riproducibile usando OpenJDK sia jdk-11.0.5e jdk1.8.0_212. Uso IntelliJ Idea e l'IDE non evidenzia tale errore, tuttavia lo solleva durante la compilazione.

Risposte

7 Andreas Aug 21 2020 at 00:00

Il motore di inferenza del compilatore Oracle / OpenJDK standard, versioni da 8 a 14, non è in grado di monitorare correttamente cosa sta succedendo.

Tuttavia, il compilatore di Eclipse può farlo, motivo per cui altri dicono di non poter riprodurre il problema.

Devi aiutarlo specificando:

Collectors.maxBy(Comparator.<Long>naturalOrder()))));     // THIS NOW WORKS