Pergunta

Eu tenho uma classe, que eu simplificado para isso:

final class Thing {
    private final int value;
    public Thing(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    @Override public String toString() {
        return Integer.toString(value);
    }
}

Eu quero classificar um array de tal coisa. Então, eu criei um copmarator simples:

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
        return a.getValue() - b.getValue();
    }
};

Em seguida, use o formulário dois argumentos de Arrays.sort.

Esta multa funciona para os meus casos de teste, mas às vezes ele vai tudo errado com a matriz de acabar em uma ordem estranha, mas repetitivo. Como pode ser isso?

Foi útil?

Solução

Integer estouro ... ou mais precisamente, underflow.

Em vez disso, fazer uma comparação explícita:

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
      int av = a.getValue(), bv = b.getValue();
      return (av == bv) ? 0 : ((av < bv) ? -1 : +1);
    }
};

Usando subtração é bom se tiver certeza de que a diferença não será "envolvente". Por exemplo, quando os valores em causa são constrangidos a ser não-negativo.

Outras dicas

Você não pode usar menos para criar a comparação. Você vai transbordar quando a diferença absoluta excede Integer.MAX_VALUE.

Em vez disso, use este algoritmo:

int compareInts( int x, int y ) {
  if ( x < y ) return -1;
  if ( x > y ) return 1;
  return 0;
}

Eu gosto de ter essa função em uma biblioteca para tais fins.

try

System.out.println(Integer.MAX_Value - Integer.MIN_VALUE);

Isso precisa retornar um número positivo como MAX_VALUE> MIN_VALUE mas sim impressões -1

Ao comparar primitivos Java, é aconselhável para convertê-los com os seus homólogos objeto e confiar em seus métodos compareTo().

Neste caso, você pode fazer:

return Integer.valueOf(a.getValue()).compareTo(b.getValue())

Em caso de dúvida, use uma biblioteca bem testado.

Que tipo de números que você jogar lá? Se os números são grandes o suficiente, você poderia envolver através dos valores MIN / MAX para números inteiros e acabam em uma bagunça.

Se o valor de um é muito negativo e valor de b é muito positiva a sua resposta será muito errado.

IIRC, Int estouro silenciosamente envolve na JVM

- MarkusQ

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top