J'ai appris à utiliser le comparable mais j'ai des difficultés avec le comparateur. J'ai une erreur dans mon 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)
Voici mon 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));
}
}
}
Je pense que cela doit faire quelque chose avec le casting dans la méthode de comparaison, mais je jouais avec et je ne pouvais toujours pas trouver la solution
Comparator<People>
,Comparable<People>
,List<People>
, etc.sort
. Si on vous dit d'utiliserComparator<People>
, utilisez l'argument 2sort
, et non l'argument 1sort
(qui requiertPeople implements Comparable<People>
).Réponses:
Il y a quelques problèmes avec votre classe d'exemple:
price
etinfo
(plus quelque chose pour les objets, pas pour les personnes);Quoi qu'il en soit, voici une démonstration de l'utilisation d'un
Comparator<T>
:ÉDITER
Et une démo équivalente de Java 8 ressemblerait à ceci:
la source
a.age - b.age
int
stackoverflow.com/questions/2728793/…Comparable
, vous devez choisir un seul attribut à comparer. Dans le cas d'une personne, il existe de nombreux attributs sur lesquels on peut comparer: l'âge, la longueur, le sexe, les noms, etc. Dans ce cas, il est facile de fournir quelques comparateurs qui effectuent ces comparaisons.Voici un modèle très court pour effectuer le tri immédiatement:
si c'est difficile à retenir, essayez de vous rappeler que c'est similaire (en termes de signe du nombre) à:
C'est au cas où vous voudriez trier par ordre croissant: du plus petit au plus grand nombre.
la source
compare()
tous les temps.Utilisez
People implements Comparable<People>
plutôt; ceci définit l'ordre naturel pourPeople
.A
Comparator<People>
peut également être défini en plus, mais cePeople implements Comparator<People>
n'est pas la bonne façon de faire les choses.Les deux surcharges pour
Collections.sort
sont différentes:<T extends Comparable<? super T>> void sort(List<T> list)
Comparable
objets en utilisant leur ordre naturel<T> void sort(List<T> list, Comparator<? super T> c)
Comparator
Vous confondez les deux en essayant de trier un
Comparator
(c'est encore une fois pourquoi cela n'a pas de sensPerson implements Comparator<Person>
). Encore une fois, pour utiliserCollections.sort
, vous avez besoin de l'un de ceux-ci pour être vrai:Comparable
(utilisez le 1-argsort
)Comparator
pour le type doit être fourni (utilisez les 2-argssort
)Questions connexes
N'utilisez pas non plus de types bruts dans le nouveau code . Les types bruts ne sont pas sûrs et sont fournis uniquement à des fins de compatibilité.
Autrement dit, au lieu de ceci:
vous devriez avoir utilisé la déclaration générique typeafe comme ceci:
Vous constaterez alors que votre code ne se compile même pas !! Ce serait une bonne chose, car il y a quelque chose qui ne va pas avec le code (
Person
nonimplements Comparable<Person>
), mais parce que vous avez utilisé le type brut, le compilateur n'a pas vérifié cela , et à la place vous obtenez unClassCastException
au moment de l'exécution !!!Cela devrait vous convaincre de toujours utiliser des types génériques de type sécurisé dans le nouveau code. Toujours.
Voir également
la source
Par souci d'exhaustivité, voici une
compare
méthode simple en une seule ligne :la source
signum
Integer.compare(lhs.getId(), rhs.getId());
est une meilleure approche. Comme @ niraj.nijju l'a mentionné, la soustraction peut provoquer un débordement.Java 8 a ajouté une nouvelle façon de créer des comparateurs qui réduit la quantité de code à écrire, Comparator.comparing . Consultez également Comparator.reversed
Voici un échantillon
la source
Vous souhaitez implémenter Comparable, pas Comparator. Vous devez implémenter la méthode compareTo. Vous êtes proche cependant. Le comparateur est une routine de comparaison «tierce». Comparable est que cet objet peut être comparé à un autre.
Remarque, vous voudrez peut-être vérifier les valeurs nulles ici pour getId..juste au cas où.
la source
Voici un exemple de comparateur qui fonctionnera pour toute méthode à zéro argument qui renvoie un comparable. Est-ce que quelque chose comme ça existe dans un jdk ou une bibliothèque?
la source
Par souci d'exhaustivité.
Utilisation de Java8
si tu veux entrer
descending order
la source
People::getId
?.thenComparing()
clause en cas de conflit..thenComparing()
?la source
La solution peut être optimisée de la manière suivante: Premièrement, utilisez une classe interne privée car la portée des champs est d'être la classe englobante TestPeople afin que l'implémentation de la classe People ne soit pas exposée au monde extérieur. Cela peut être compris en termes de création d'une API qui attend une liste triée de personnes Deuxièmement, en utilisant l'expression Lamba (java 8) qui réduit le code, d'où l'effort de développement
Par conséquent, le code serait comme ci-dessous:
la source
Vous devez utiliser la méthode de tri surchargé (peps, new People ())
la source
Voici ma réponse pour un simple outil de comparaison
}
Outil utilitaire pour le même
}
Classe d'informations de colonne
la source
Deux corrections:
Vous devez faire un
ArrayList
desPeople
objets:Après avoir ajouté les objets aux préparations, utilisez:
Ajoutez également une
CompareId
classe comme:la source
Ne perdez pas de temps à mettre en œuvre l'algorithme de tri par vous-même. Au lieu; utilisation
Collections.sort () pour trier les données.
la source