El método de comparación de arreglos viola su error de contrato general en Java
-
Diferencia entre las interfaces
Comparador
yComparable
-
Reglas de comparación para
Comparador
yComparable
-
Código Java Tener el
método de comparación viola su contrato general
Error -
Soluciones Java utilizando las interfaces
Comparator
yComparable
Hoy, aprenderemos sobre las reglas de comparación utilizadas por las interfaces Comparator
y Comparable
, lo que conducirá a las posibles causas del error el método de comparación viola su contrato general
en Java. Después de eso, entenderemos dos soluciones usando las interfaces Comparador
y Comparable
.
Diferencia entre las interfaces Comparador
y Comparable
Estas son dos interfaces en las bibliotecas principales de Java. El Comparador
es una función que compara dos objetos diferentes y es independiente de todo lo demás.
Solo busca sus dos entradas, continúa su proceso con ellas y presenta los resultados.
Por otro lado, el Comparable
es una interfaz que mezclamos con una clase de datos. Por ejemplo, tenemos una clase con algunos datos; la interfaz Comparable
se utilizará para comparar el primer objeto de esta clase con el segundo objeto de la misma clase.
Significa que la interfaz Comparable
indica que esta
instancia se puede comparar con otra instancia de la misma clase. Recuerde, el Comparable
define el orden natural
para la clase.
En otros aspectos, también es una función de comparación al igual que el Comparador
y tiene las mismas reglas para el valor devuelto, transitivo, reflexivo, etc.
Reglas de comparación para Comparador
y Comparable
El método de comparación viola su contrato general
significa que el Comparador
o Comparable
(según lo que estemos usando) tiene un error y viola una de las reglas de consistencia. ¿Cuáles son las reglas de coherencia?
Aprendamos a continuación.
Suponemos que hemos escrito nuestro programa Java para valores de tipo entero. Por lo tanto, nuestra función de comparación debe cumplir con las siguientes reglas.
-
Dados dos números enteros
a
yb
cualesquiera, se debe cumplir la Ley de la Tricotomía, lo que significa que se debe cumplir exactamente una de las siguientes relaciones:a
es menor queb
(devuelve el valor-ve
sia < b
)a
es igual ab
(devuelve0
sia == b
)a
es mayor queb
(devuelve valor+ve
sia > b
)
-
Debe satisfacer la Transitividad, es decir, si
a < b
yb < c
entonces, para cualesquiera tres númerosa
,b
,c
, implicaa < c
. -
La tercera regla es sobre Antisimetría, donde
a < b
implica~b < a
-
La sustituibilidad es también una regla de comparación que dice, supongamos,
a == b
ya < c
; esto implicab < c
. -
La última regla de comparación es la Reflexividad, donde
a == a
; también~a < a
.
Si se viola alguna de estas reglas, obtenemos el error que dice que el método de comparación viola su contrato general
. Aprendamos con la ayuda de un ejemplo de código a continuación.
Código Java Tener el método de comparación viola su contrato general
Error
Código de ejemplo:
// import libraries
import static java.util.stream.Collectors.toCollection;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
// Main
public class Main {
public static void main(String[] args) {
// generate random numbers
List<Integer> list = new Random(209).ints(32L).boxed().collect(toCollection(ArrayList::new));
// sort using lambda expression
list.sort(logging((a, b) -> a - b));
} // end main()
// logging the comparisons
static Comparator<Integer> logging(Comparator<Integer> c) {
return (a, b) -> {
int r = c.compare(a, b);
System.err.printf("%,14d %,14d => %,14d\n", a, b, r);
return r;
};
} // end logging()
} // end class
En este código, estamos generando algunos números aleatorios usando la instancia ints
de la clase Random
, que se usa para generar el flujo de números aleatorios.
Para este código, si ordenamos como list.sort((a, b) -> a - b);
entonces, no podremos identificar cuál es el problema y dónde está ocurriendo. Por eso lo estamos ordenando mediante logging
, que nos ayudará a identificarlo.
Nos da un error, pero también proporciona muchas comparaciones de números. No discutiremos todos, pero algunos de ellos son suficientes para encontrar el error.
PRODUCCIÓN:
Como podemos ver, el programa viola aquí la regla de coherencia, lo que genera este error. En la siguiente sección, tengamos la solución usando Comparador
y Comparable
.
Soluciones Java utilizando las interfaces Comparator
y Comparable
Usemos la interfaz Comparador
con menos números aleatorios.
Código de ejemplo:
// import libraries
import static java.util.stream.Collectors.toCollection;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
// Main
public class Main {
public static void main(String[] args) {
// generate random numbers
List<Integer> list = new Random(5).ints(32L).boxed().collect(toCollection(ArrayList::new));
// sort using lambda expression
list.sort(logging((a, b) -> a - b));
} // end main()
// logging the comparisons
static Comparator<Integer> logging(Comparator<Integer> c) {
return (a, b) -> {
int r = c.compare(a, b);
System.err.printf("%,14d %,14d => %,14d\n", a, b, r);
return r;
};
} // end logging()
} // end class
Este código se ejecuta con éxito. No estamos revisando todas las comparaciones, pero veremos algunas de ellas para confirmar.
Verifique la siguiente captura de pantalla.
PRODUCCIÓN:
Aprendamos sobre el código Java sin errores usando la interfaz Comparable
para hacer comparaciones. Para usar esta interfaz, tenemos que crear una clase que contenga datos.
Hagámoslo a continuación.
Código de ejemplo (clase Students.java
):
public class Student implements Comparable<Student> {
private String firstName;
private String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int compareTo(Student other) {
/*
compare the last names and save the result
in `compareResult` variable
*/
int compareResult = this.lastName.compareTo(other.lastName);
/*
If both last names match, then it would be true means 0. So,
dive into the `if` condition and check if the count of their
first name matches.
if this.count == other.count return 0
if this.count > other.count return 1
if this.count < other.count return -1
*/
if (compareResult == 0) {
if (this.firstName.chars().count() == other.firstName.chars().count()) {
compareResult = 0;
return compareResult;
} else if (this.firstName.chars().count() > other.firstName.chars().count()) {
compareResult = 1;
return compareResult;
} else {
compareResult = -1;
return compareResult;
}
} else {
return compareResult;
}
}
}
Código de ejemplo (clase Main.java
):
public class Main {
public static void main(String[] args) {
Student std1 = new Student("Mehvish", "Ashiq");
Student std2 = new Student("Mehvish", "Ashiq");
System.out.println("Result of Comparison 1: " + std1.compareTo(std2));
Student std3 = new Student("Aftab", "Ashiq");
Student std4 = new Student("Mehvish", "Ashiq");
System.out.println("Result of Comparison 2: " + std3.compareTo(std4));
Student std5 = new Student("Mehr-un-nissa", "Ashiq");
Student std6 = new Student("Mehvish", "Ashiq");
System.out.println("Result of Comparison 3: " + std5.compareTo(std6));
}
}
Producción :
Result of Comparison 1: 0
Result of Comparison 2: -1
Result of Comparison 3: 1
En este código, comparamos el recuento de letras de firstName
si el lastName
de dos objetos es el mismo.
Como podemos ver, los resultados son consistentes. Si a==b
, a<b
y a>b
, devuelve 0
, -1
y 1
, respectivamente.
Artículo relacionado - Java Error
- Arreglar Java fue iniciado por el código de salida devuelto = 1
- Arreglar JAVA_HOME no se puede determinar a partir del error de registro en R
- Arreglar java.io.IOException: No queda espacio en el dispositivo en Java
- Arreglar Java.IO.NotSerializableException en Java
- Arreglar Java.Lang.IllegalStateException de Android: no se pudo ejecutar el método de la actividad
- Arreglar Java.Lang.NoClassDefFoundError: No se pudo inicializar el error de clase