Comparador .comparing (). Invertida () extraño comportamiento / no funciona como se esperaba

Arun Gowda:

Según mi conocimiento, Comparator.comparingInt()debe ordenar en orden ascendente y Comparator.comparingInt().reverseddebe ordenar en orden descendente. Pero me encontré con un escenario en el que esto es inversa.

Esto se explica mejor con un ejemplo. Lo que sigue es mi código.

clase Monto:

class Amount
{
    int lineNum;
    int startIndex;
    Double value;
//Getters , setters and toString.
}

Método principal:

public static void main( String[] args )
{
    List<Amount> amounts = new ArrayList<>();
    amounts.add( new Amount( 1.0, 5, 10 ) ); //LINE_NUM 5
    amounts.add( new Amount( 3.0, 9, 30 ) );
    amounts.add( new Amount( 2.0, 3, 40 ) );
    amounts.add( new Amount( 9.0, 5, 20 ) ); //LINE_NUM 5
    amounts.add( new Amount( 6.0, 1, 50 ) );
    amounts.add( new Amount( 4.0, 5, 20 ) ); //LINE_NUM 5
    System.out.println( ".............BEFORE SORTING.........." );
    amounts.forEach( System.out::println );


    amounts.sort( 
                 Comparator.comparingInt( Amount::getLineNum )   //NOTE THIS
        .           .thenComparingInt( Amount::getStartIndex ).reversed()
                      .thenComparingDouble( Amount::getValue ) );

    System.out.println( "\n\n.............AFTER SORTING.........." );

    amounts.forEach( System.out::println );
}

Quería indique monto ordenado por lineNum ascendente, descendente y por startIndex valor ascendente.

Así que mi expectativa era esto.

............. CLASIFICACIÓN TRAS .......... ( ESPERA )

Cantidad [lineNum = 1, startIndex = 50, el valor = 6.0]

Cantidad [lineNum = 3, startIndex = 40, el valor = 2.0]

Cantidad [lineNum = 5, startIndex = 20, el valor = 4.0]

Cantidad [lineNum = 5, startIndex = 20, el valor = 9.0]

Cantidad [lineNum = 5, startIndex = 10, el valor = 1.0]

Cantidad [lineNum = 9, startIndex = 30, el valor = 3.0]

............. CLASIFICACIÓN TRAS .......... ( REAL )

Cantidad [lineNum = 9, startIndex = 30, el valor = 3.0]

Cantidad [lineNum = 5, startIndex = 20, el valor = 4.0]

Cantidad [lineNum = 5, startIndex = 20, el valor = 9.0]

Cantidad [lineNum = 5, startIndex = 10, el valor = 1.0]

Cantidad [lineNum = 3, startIndex = 40, el valor = 2.0]

Cantidad [lineNum = 1, startIndex = 50, el valor = 6.0]

Todo se exceptúa el adecuado para el fin lineNum . Las cantidades fueron ordenados por lineNumber descendente mientras yo estaba esperando a estar en orden ascendente .

Los resultados fueron los esperados cuando cambié Comparador de seguir

amounts.sort(
    Comparator.
    comparingInt( Amount::getLineNum ).reversed()
    .thenComparingInt( Amount::getStartIndex ).reversed()
    .thenComparingDouble( Amount::getValue ) );

Lo cual es extraño porque, comparingInt( Amount::getLineNum ).reversed()se supone que las cantidades ordenar por número de línea descendente.

Una cosa más que he notado es, Comparando por StartIndex funciona como se esperaba. Pero Comparando por lineNumber parte no lo es.

¿Alguien puede explicar esto?

Jon Skeet:

Es más fácil de entender lo que está pasando si se pone cada llamada en una línea:

Comparator.comparingInt(Amount::getLineNum)
    .thenComparingInt(Amount::getStartIndex)
    .reversed()
    .thenComparingDouble(Amount::getValue)

Que reversed()devuelve un comparador que invierte los resultados del comparador se llama en ... que es "el primer comparador que compara el número de línea, entonces el índice de inicio." No es como si fuera "corchetes" sólo al alcance de la anterior thenComparingInt()convocatoria, que es como su formato anterior hace que parezca.

Se podía hacerlo como:

Comparator.comparingInt(Amount::getLineNum)
    .thenComparing(Comparator.comparingInt(Amount::getStartIndex).reversed())
    .thenComparingDouble(Amount::getValue)

En ese momento es sólo la comparación de índice de inicio que invierten.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=172357&siteId=1
Recomendado
Clasificación