J'essaie de trier mon chromosome de classe personnalisé en fonction de la valeur de leur attribut score, qui est un double. Ces chromosomes sont stockés dans une ArrayList. Je sais que je dois utiliser un comparateur, mais j’ai lu tellement d’opinions divergentes en ligne au cours de la dernière heure que je suis complètement confus.
Ci-joint mon code, si quelqu'un pouvait me diriger dans la bonne direction, je serais très apprécié.
public class Chromosome
{
public Gene[] genes;
public double score;
public Chromosome(int l)
{
genes = new Gene[l];
}
public int getLength()
{
return genes.length;
}
public void printChromo()
{
for(int i=0;i<this.genes.length;i++)
{
System.out.println(""+this.genes[i].teacher+","+
this.genes[i].lecture+","+
this.genes[i].room+","+
this.genes[i].time+"");
}
}
public void setScore(double score)
{
this.score=score;
}
public double getScore()
{
return this.score;
}
}
Je ne sais pas si cela fait une différence, mais le score ne peut être qu'un double entre 0.0 et 1.0.
Pour utiliser une Comparator
:
Collections.sort(myList, new Comparator<Chromosome>() {
@Override
public int compare(Chromosome c1, Chromosome c2) {
return Double.compare(c1.getScore(), c2.getScore());
}
});
Si vous envisagez de trier de nombreux List
s de cette manière, je vous suggèrerais que Chromosome
implémente l'interface Comparable
(dans ce cas, vous pouvez simplement appeler Collections.sort(myList)
, sans qu'il soit nécessaire de spécifier un Comparator
explicite).
Je mettrais en œuvre l'interface Comparable :
public class Chromosome implements Comparable<Chromosome>{
private double score;
public Chromosome(double score){
this.score = score;
}
@Override
public int compareTo(Chromosome o) {
return new Double(score).compareTo( o.score);
}
@Override
public String toString() {
return String.valueOf(score);
}
}
Notez que je me suis déplacé score dans la classe ..
Maintenant, vous pouvez utiliser n'importe quel Collection qui est trié (comme un TreeSet )
Si vous insistez pour utiliser l'Arraylist, vous pouvez utiliser:
ArrayList<Chromosome> out = new ArrayList<Chromosome>();
out.add(new Chromosome(20));
out.add(new Chromosome(15));
System.out.println(out);
Collections.sort(out);
System.out.println(out);
Résultat:
[0.2, 0.15]
[0.15, 0.2]
Pourquoi ne pas utiliser un PriorityQueue avec un Comparateur comme ceci:
// your code
PriorityQueue<Chromosome> entries = new PriorityQueue<Chromosome>(1, new Comparator<Chromosome> () {
@Override
public int compare(Chromosome arg0, Chromosome arg1) {
return (Double)(arg1.getScore()).compareTo((Double)arg0.getScore());
}
});
entries.addAll(arrayListOfChromosomes);
// your code
La file d'attente prioritaire conservera alors votre structure de données dans un ordre trié.
Depuis Java 8, vous pouvez trier la liste des éléments Double très simple.
list.sort(Comparator.comparingDouble(Chromosome::getScore));
ou
Collections.sort(list, omparator.comparingDouble(Chromosome::getScore));
Si vous voulez obtenir une liste triée mais que vous ne voulez pas changer votre liste de début, vous pouvez le faire comme suit:
List<Chromosome> sortedList = list.stream()
.sorted(Comparator.comparingDouble(A::getScore))
.collect(Collectors.toList());
Avec Java SE8 , vous pouvez utiliser une expression lambda comme ceci:
list.sort((o1, o2) -> Double.compare(o2.doubleField, o1.doubleField));