Ich habe gelernt, wie man das Vergleichbare benutzt, aber ich habe Schwierigkeiten mit dem Komparator. Ich habe einen Fehler in meinem Code:
Exception in thread "main" java.lang.ClassCastException: New.People cannot be cast to java.lang.Comparable
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at New.TestPeople.main(TestPeople.java:18)
Hier ist mein Code:
import java.util.Comparator;
public class People implements Comparator {
private int id;
private String info;
private double price;
public People(int newid, String newinfo, double newprice) {
setid(newid);
setinfo(newinfo);
setprice(newprice);
}
public int getid() {
return id;
}
public void setid(int id) {
this.id = id;
}
public String getinfo() {
return info;
}
public void setinfo(String info) {
this.info = info;
}
public double getprice() {
return price;
}
public void setprice(double price) {
this.price = price;
}
public int compare(Object obj1, Object obj2) {
Integer p1 = ((People) obj1).getid();
Integer p2 = ((People) obj2).getid();
if (p1 > p2) {
return 1;
} else if (p1 < p2){
return -1;
} else {
return 0;
}
}
}
import java.util.ArrayList;
import java.util.Collections;
public class TestPeople {
public static void main(String[] args) {
ArrayList peps = new ArrayList();
peps.add(new People(123, "M", 14.25));
peps.add(new People(234, "M", 6.21));
peps.add(new People(362, "F", 9.23));
peps.add(new People(111, "M", 65.99));
peps.add(new People(535, "F", 9.23));
Collections.sort(peps);
for (int i = 0; i < peps.size(); i++){
System.out.println(peps.get(i));
}
}
}
Ich glaube, es hat etwas mit dem Casting in der Vergleichsmethode zu tun, aber ich habe damit herumgespielt und konnte immer noch keine Lösung finden
java
sorting
comparator
Dan
quelle
quelle
Comparator<People>
,Comparable<People>
,List<People>
etc.sort
. Wenn Sie aufgefordert werden, zu verwendenComparator<People>
, verwenden Sie das 2-Argumentsort
, nicht das 1-Argumentsort
(was erforderlich istPeople implements Comparable<People>
).Antworten:
In Ihrer Beispielklasse gibt es einige unangenehme Dinge:
price
und hatinfo
(mehr etwas für Objekte, nicht Menschen);Wie auch immer, hier ist eine Demo zur Verwendung von
Comparator<T>
:BEARBEITEN
Und eine äquivalente Java 8-Demo würde folgendermaßen aussehen:
quelle
a.age - b.age
int
stackoverflow.com/questions/2728793/…Comparable
müssen Sie jedoch ein einzelnes Attribut auswählen, mit dem Sie vergleichen möchten. Im Falle einer Person gibt es viele Attribute, mit denen man vergleichen kann: Alter, Länge, Geschlecht, Namen usw. In diesem Fall ist es einfach, einige Komparatoren bereitzustellen, die diese Vergleiche durchführen.Hier ist eine super kurze Vorlage, um die Sortierung sofort durchzuführen:
Wenn es schwer zu merken ist, versuchen Sie sich daran zu erinnern, dass es ähnlich ist (in Bezug auf das Vorzeichen der Zahl) wie:
Dies ist der Fall, wenn Sie in aufsteigender Reihenfolge sortieren möchten: von der kleinsten zur größten Zahl.
quelle
compare()
aller Zeiten.Verwenden Sie
People implements Comparable<People>
stattdessen; Dies definiert die natürliche Reihenfolge fürPeople
.A
Comparator<People>
kann aber auch zusätzlich definiert werdenPeople implements Comparator<People>
nicht die richtige Vorgehensweise.Die zwei Überladungen für
Collections.sort
sind unterschiedlich:<T extends Comparable<? super T>> void sort(List<T> list)
Comparable
Objekte anhand ihrer natürlichen Reihenfolge<T> void sort(List<T> list, Comparator<? super T> c)
Comparator
Sie verwechseln die beiden, indem Sie versuchen, a zu sortieren
Comparator
(weshalb dies wiederum keinen Sinn ergibtPerson implements Comparator<Person>
). Um es zu verwendenCollections.sort
, benötigen Sie eines davon, um wahr zu sein:Comparable
(verwenden Sie das 1-Argumentsort
)Comparator
für den Typ muss angegeben werden (verwenden Sie die 2-Argumentesort
)Verwandte Fragen
Ebenfalls, verwenden Sie keine rohen Typen in neuen Code . Raw-Typen sind unsicher und werden nur aus Kompatibilitätsgründen bereitgestellt.
Das heißt, stattdessen:
Sie hätten die typsichere generische Deklaration wie folgt verwenden sollen:
Sie werden dann feststellen, dass Ihr Code nicht einmal kompiliert wird !! Das wäre eine gute Sache, da mit dem Code etwas nicht stimmt (
Person
nichtimplements Comparable<Person>
), aber weil Sie den Rohtyp verwendet haben, hat der Compiler dies nicht überprüft , und stattdessen erhalten Sie eineClassCastException
zur Laufzeit eine !!!Dies sollte Sie überzeugen, immer typsichere generische Typen in neuem Code zu verwenden. Immer.
Siehe auch
quelle
Der Vollständigkeit halber ist hier eine einfache Einzeiler-
compare
Methode:quelle
signum
Integer.compare(lhs.getId(), rhs.getId());
ist ein besserer Ansatz. Wie bei @ niraj.nijju erwähnt, kann die Subtraktion einen Überlauf verursachen.8 Java hat einen neuen Weg Comparators machen , dass die Menge an Code reduzieren Sie schreiben müssen, Comparator.comparing . Schauen Sie sich auch Comparator.reversed an
Hier ist ein Beispiel
quelle
Sie möchten Comparable implementieren, nicht Comparator. Sie müssen die compareTo-Methode implementieren. Du bist aber nah dran. Der Komparator ist eine Vergleichsroutine "von Drittanbietern". Vergleichbar ist, dass dieses Objekt mit einem anderen verglichen werden kann.
Beachten Sie, dass Sie hier nach Nullen für getId suchen möchten. Nur für den Fall.
quelle
Hier ist ein Beispiel für einen Komparator, der für jede Null-Arg-Methode funktioniert, die eine Vergleichbare zurückgibt. Gibt es so etwas in einem JDK oder einer Bibliothek?
quelle
Der Vollständigkeit halber.
Verwenden von Java8
wenn du rein willst
descending order
quelle
People::getId
?.thenComparing()
Klausel hinzufügen , wenn es zu einem Konflikt kommt..thenComparing()
?quelle
Die Lösung kann auf folgende Weise optimiert werden: Verwenden Sie zunächst eine private innere Klasse, da der Bereich für die Felder die einschließende Klasse TestPeople sein soll, damit die Implementierung der Klasse People nicht der Außenwelt ausgesetzt wird. Dies kann im Hinblick auf das Erstellen einer API verstanden werden, die eine sortierte Liste von Personen erwartet. Zweitens wird der Lamba-Ausdruck (Java 8) verwendet, der den Code und damit den Entwicklungsaufwand reduziert
Daher wäre der Code wie folgt:
quelle
Sie sollten die überladene Sortiermethode (peps, new People ()) verwenden
quelle
Hier ist meine Antwort für ein einfaches Vergleichstool
}}
Utility Tool für das gleiche
}}
Spalteninfo-Klasse
quelle
Zwei Korrekturen:
Sie müssen eine machen
ArrayList
vonPeople
Objekten:Verwenden Sie nach dem Hinzufügen der Objekte zu den Vorbereitungen:
Fügen Sie außerdem eine
CompareId
Klasse hinzu als:quelle
Verschwenden Sie keine Zeit damit, den Sortieralgorithmus selbst zu implementieren. Stattdessen; verwenden
Collections.sort () zum Sortieren von Daten.
quelle