Fix-Vergleichsmethode verletzt ihren allgemeinen Vertragsfehler in Java
-
Unterschied zwischen
Komparator
- undvergleichbaren
Schnittstellen -
Vergleichsregeln für
Vergleicher
undVergleichbar
-
Java-Code mit dem Fehler
Vergleichsmethode verstößt gegen ihren allgemeinen Vertrag
-
Java-Lösungen mit den Schnittstellen
Comparator
undComparable
Heute lernen wir die von den Schnittstellen Comparator
und Comparable
verwendeten Vergleichsregeln kennen, die zu möglichen Ursachen für den Fehler Vergleichsmethode verletzt seinen allgemeinen Vertrag
in Java führen. Danach werden wir zwei Lösungen verstehen, die die Schnittstellen Comparator
und Comparable
verwenden.
Unterschied zwischen Komparator
- und vergleichbaren
Schnittstellen
Dies sind zwei Schnittstellen in Java-Kernbibliotheken. Der Comparator
ist eine Funktion, die zwei verschiedene Objekte vergleicht und von allem anderen unabhängig ist.
Es sucht nur nach seinen beiden Eingaben, setzt seinen Prozess mit ihnen fort und präsentiert die Ergebnisse.
Andererseits ist das Comparable
eine Schnittstelle, die wir mit einer Datenklasse mischen. Zum Beispiel haben wir eine Klasse mit einigen Daten; die Comparable
-Schnittstelle wird verwendet, um das erste Objekt dieser Klasse mit dem zweiten Objekt derselben Klasse zu vergleichen.
Das bedeutet, dass die Schnittstelle Vergleichbar
anzeigt, dass diese
Instanz mit einer anderen Instanz derselben Klasse verglichen werden kann. Denken Sie daran, dass Vergleichbar
die natürliche
Reihenfolge für die Klasse definiert.
Ansonsten ist sie ebenso eine Vergleichsfunktion wie der Comparator
und hat die gleichen Regeln für den Rückgabewert, transitiv, reflexiv usw.
Vergleichsregeln für Vergleicher
und Vergleichbar
Die Vergleichsmethode verletzt ihren allgemeinen Vertrag
bedeutet, dass der Vergleicher
oder Vergleichbar
(basierend auf dem, was wir verwenden) einen Fehler hat und gegen eine der Konsistenzregeln verstößt. Welche Konsistenzregeln gibt es?
Lassen Sie uns sie unten lernen.
Wir gehen davon aus, dass wir unser Java-Programm für ganzzahlige Werte geschrieben haben. Daher muss unsere Vergleichsfunktion die folgenden Regeln einhalten.
-
Bei zwei beliebigen ganzen Zahlen
a
undb
muss das Trichotomiegesetz erfüllt sein, was bedeutet, dass genau eine der folgenden Beziehungen wahr sein muss:a
ist kleiner alsb
(es gibt den Wert-ve
zurück, wenna < b
)a
ist gleichb
(gibt0
zurück, wenna == b
)a
ist größer alsb
(es gibt den Wert+ve
zurück, wenna > b
)
-
Es muss die Transitivität erfüllen, was bedeutet, wenn
a < b
undb < c
, dann impliziert es für drei beliebige Zahlena
,b
,c
a < c
. -
Die dritte Regel betrifft die Antisymmetrie, wobei
a < b
~b < a
impliziert -
Substituierbarkeit ist auch eine Vergleichsregel, die sagt, angenommen,
a == b
unda < c
; dies impliziertb < c
. -
Die letzte Vergleichsregel ist Reflexivität, wobei
a == a
; auch~a < a
.
Wird gegen eine dieser Regeln verstoßen, erhalten wir die Fehlermeldung Vergleichsmethode verstößt gegen ihren allgemeinen Vertrag
. Lassen Sie es uns anhand eines Codebeispiels unten lernen.
Java-Code mit dem Fehler Vergleichsmethode verstößt gegen ihren allgemeinen Vertrag
Beispielcode:
// 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
In diesem Code generieren wir einige Zufallszahlen, indem wir die Instanz ints
der Klasse Random
verwenden, die zum Generieren des Stroms von Zufallszahlen verwendet wird.
Für diesen Code sortieren wir als list.sort((a, b) -> a - b);
dann können wir nicht erkennen, was das Problem ist und wo es auftritt. Deshalb sortieren wir sie via logging
, was uns hilft, sie zu identifizieren.
Es gibt uns einen Fehler, aber es bietet auch viele Vergleiche von Zahlen. Wir werden nicht alle besprechen, aber einige davon reichen aus, um den Fehler zu finden.
AUSGANG:
Wie wir sehen können, verletzt das Programm hier die Konsistenzregel, was zu diesem Fehler führt. Lassen Sie uns im nächsten Abschnitt die Lösung mit Comparator
und Comparable
haben.
Java-Lösungen mit den Schnittstellen Comparator
und Comparable
Verwenden wir die Comparator
-Schnittstelle mit weniger Zufallszahlen.
Beispielcode:
// 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
Dieser Code wird erfolgreich ausgeführt. Wir gehen nicht alle Vergleiche durch, aber wir werden einige davon sehen, um sie zu bestätigen.
Überprüfen Sie den folgenden Screenshot.
AUSGANG:
Erfahren Sie mehr über den fehlerfreien Java-Code mit der Vergleichsschnittstelle Comparable
. Um diese Schnittstelle zu verwenden, müssen wir eine Klasse erstellen, die Daten enthält.
Lass es uns unten tun.
Beispielcode (Klasse 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;
}
}
}
Beispielcode (Klasse 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));
}
}
AUSGANG:
Result of Comparison 1: 0
Result of Comparison 2: -1
Result of Comparison 3: 1
In diesem Code vergleichen wir die Buchstabenanzahl von firstName
, wenn der lastName
zweier Objekte gleich ist.
Wie wir sehen können, sind die Ergebnisse konsistent. Wenn a==b
, a<b
und a>b
, wird jeweils 0
, -1
und 1
zurückgegeben.
Verwandter Artikel - Java Error
- Adresse wird bereits verwendet JVM_Bind-Fehler in Java
- Android Java.Lang.IllegalStateException behoben: Methode der Aktivität konnte nicht ausgeführt werden
- Ausnahme im Hauptthread Java.Lang.ClassNotFoundException in IntelliJ IDEA
- Ausnahme im Hauptthread Java.Lang.NoClassDefFoundError
- Beheben Sie das Problem, dass Java nicht installiert werden kann. Es gibt Fehler in den folgenden Schaltern
- Beheben Sie den Fehler `Es wurde keine Java Virtual Machine gefunden` in Eclipse