Pregunta

Tengo una clase, que he simplificado a esto:

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);
    }
}

Quiero ordenar una matriz de esta cosa. Así que he creado un copmarator simple:

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

Luego uso la forma de dos argumentos de Arrays.sort .

Esto funciona bien para mis casos de prueba, pero a veces no funciona bien con el arreglo que termina en un orden extraño pero repetible. ¿Cómo puede ser esto?

¿Fue útil?

Solución

Desbordamiento de enteros ... o más precisamente, subdesbordamiento.

En su lugar, haz una comparación 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);
    }
};

El uso de la resta está bien si está seguro de que la diferencia no se ajustará a " ;. Por ejemplo, cuando los valores en cuestión se limitan a no ser negativos.

Otros consejos

No puedes usar menos para crear la comparación. Se desbordará cuando la diferencia absoluta supere Integer.MAX_VALUE .

En su lugar, usa este algoritmo:

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

Me gusta tener esta función en una biblioteca para tales fines.

prueba

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

Esto debe devolver un número positivo como MAX_VALUE > MIN_VALUE pero en su lugar imprime -1

Al comparar primitivos de Java, es recomendable convertirlos a sus contrapartes de objetos y confiar en sus métodos compareTo () .

En este caso puedes hacer:

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

En caso de duda, utilice una biblioteca bien probada.

¿Qué tipo de números arrojas allí? Si sus números son lo suficientemente grandes, podría ajustar los valores MIN / MAX para los enteros y terminar en un desastre.

Si el valor de a es muy negativo y el valor de b es muy positivo, su respuesta será muy incorrecta.

IIRC, Int overflow se envuelve silenciosamente en la JVM

- MarkusQ

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top