¿por qué mi método de comparación arrojar excepción – método de comparación viola su contrato general!

¿Por qué este código

public class SponsoredComparator implements Comparator<SRE> { public boolean equals(SRE arg0, SRE arg1){ return arg0.getSponsored()==arg1.getSponsored(); } public int compare(SRE object1, SRE object2) { Log.d("SponsoredComparator","object1.getName() == "+ object1.getName()); Log.d("SponsoredComparator","object1.getSponsored() == "+ object1.getSponsored()); Log.d("SponsoredComparator","object2.getName() == "+ object2.getName()); Log.d("SponsoredComparator","object2.getSponsored() == "+ object2.getSponsored()); Log.d("SponsoredComparator","compare return == "+ (object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1)); return object1.getSponsored() && object2.getSponsored() ? 0 : object1.getSponsored() ? -1 : 1; } } 

lanzar esta excepción: ERROR/AndroidRuntime(244): java.lang.IllegalArgumentException: Comparison method violates its general contract!
ERROR/AndroidRuntime(4446): at java.util.TimSort.mergeLo(TimSort.java:743)
ERROR/AndroidRuntime(244): java.lang.IllegalArgumentException: Comparison method violates its general contract!
ERROR/AndroidRuntime(4446): at java.util.TimSort.mergeLo(TimSort.java:743)

El método sre.getSponsored () devuelve un booleano.

Gracias.

Sospecho que el problema se produce cuando no se patrocina ningún valor. Eso volverá 1 como usted lo llame, es decir

 x1.compare(x2) == 1 x2.compare(x1) == 1 

Eso no es válido.

Le sugiero que cambie esto:

 object1.getSponsored() && object2.getSponsored() 

a

 object1.getSponsored() == object2.getSponsored() 

en ambos lugares. Probablemente extraería un método con esta firma en algún lugar:

 public static int compare(boolean x, boolean y) 

y luego lo llaman así:

 public int compare(SRE object1, SRE object2) { return BooleanHelper.compare(object1.getSponsored(), object2.getSponsored()); } 

Eso hará que el código sea más claro, IMO.

Supongo que está utilizando JDK 7. Compruebe la URL siguiente:

Desde http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#source

Área: API: Utilidades

Sinopsis: El comportamiento de ordenación actualizado de Arrays y Collections puede arrojar una IllegalArgumentException

Descripción: Se ha reemplazado el algoritmo de clasificación utilizado por java.util.Arrays.sort y (indirectamente) por java.util.Collections.sort . La nueva implementación de ordenación puede lanzar una IllegalArgumentException si detecta un Comparable que viola el contrato Comparable . La implementación anterior silenciosamente ignoró tal situación. Si se desea el comportamiento anterior, puede utilizar la nueva propiedad del sistema, java.util.Arrays.useLegacyMergeSort , para restaurar el comportamiento anterior de mergesort.

Naturaleza de la Incompatibilidad: conductual

RFE: 6804124

Para obtener información más detallada, consulte la referencia de la base de datos de errores aquí .

El contrato entre iguales () y compararTo () es que cuando equals () devuelve true, compareTo () devuelve 0 y cuando es igual () es false compareTo devuelve -1 o +1.

BTW: Supongo que su método compare () no se llama con mucha frecuencia ya que los mensajes de depuración utilizarán una cantidad significativa de CPU y memoria.

Estoy de acuerdo con todas las respuestas especialmente con jon, pero una addinal cosas que quiero decir que siempre debe comprobar la seguridad nula en comparar el método para que nuestro método nunca se romper y es un buen hábito en la programación para siempre nulo de control. Para más información, mira aquí

tal vez usted acaba de tener NaN valores que se comparan a través de Collections.sort … esto ha sido un problema para mí y tengo esa excepción, incluso teniendo la aplicación correcta de comparar (obj1, obj2) método! ¡Mira esto!

Tengo el mismo problema hoy en una aplicación web. Cuatro llamadas que trabajan en la misma matriz trataron de ordenar al mismo tiempo, con eficacia desorden el uno para el otro.

  • Anula la versión de Java cuando construye un proyecto Cordova con gradle
  • Comprobar si existe una entrada en una base de datos
  • ¿Es la agrupación de objetos pequeños más eficiente que el recolector de basura Java de Android?
  • Reproducción de música BG en actividades en Android
  • ¿Cómo implementar la facturación en la aplicación en una aplicación de Android?
  • Java: Necesita alguna manera de acortar este código
  • ¿Utilizando color y color.darker en Android?
  • Voice Matcher para combinar la contraseña de voz en Android (Comparar voz)
  • Progreso intermedio no funciona con ActionBarSherlock ejecutándose en Gingerbread
  • Excepción de interrupción de subproceso en modo Multi-ventana
  • Encriptación de Android "bloque pad bloqueado" excepción
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.