30

I'm trying to sort my custom class chromosome by the value of their score attribute which is a double. These chromosomes are stored within an ArrayList. I know I have to use a comparator but I've read so many differing opinions online in the last hour that I'm utterly confused.

Attached is my code, if someone could point me in the right direction I would be much appreciated.

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;
    }
}

Don't know this make a difference but the score can only be a double between and including 0.0 to 1.0

1
  • found this question while google "java double sort" for my genetic alghorithm Commented Dec 24, 2016 at 19:10

5 Answers 5

79

To use a Comparator:

Collections.sort(myList, new Comparator<Chromosome>() {
    @Override
    public int compare(Chromosome c1, Chromosome c2) {
        return Double.compare(c1.getScore(), c2.getScore());
    }
});

If you plan on sorting numerous Lists in this way I would suggest having Chromosome implement the Comparable interface (in which case you could simply call Collections.sort(myList), without the need of specifying an explicit Comparator).

Sign up to request clarification or add additional context in comments.

3 Comments

How would I get it an ascending list?
@Melo1991 There is a Collections.reverse method if that's what you're after.
Or just c2.compareTo(c1) instead of c1.compareTo(c2).
12

With Java SE8 you could use lambda expression like so:

list.sort((o1, o2) -> Double.compare(o2.doubleField, o1.doubleField));

Comments

3

Why not use a PriorityQueue with a Comparator like this:

// 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

The priority queue will then keep your data structure in sorted order.

2 Comments

Would I have this piece of code within my main class where I create my actual arrayList?
You could, or instead of the entire ArrayList, you call .add on every Chromosome.
3

I would implement the 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);
    }
}

Note that i moved score inside the Class..

Now you can use any Collection that is Sorted (like a TreeSet)

If you insist on using the Arraylist you can use:

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);

Result:

[0.2, 0.15]
[0.15, 0.2]

6 Comments

When using this and I want to sort the arrayList I call the collections.sortmethod yes? Could you please tell me how to do that? @Frank
Or if you do not want to implement the Comparable interface, you can use the Collections.sort( List<T>, Comparator<? super T> ) method
I've tried using this code @Frank and it still won't sort it :-(
I added a proof of concept, note that i also refined the compareTo method.
See the input in the Chromosome constructor is setting the amount of genes of the chromosome. Score is the fitness function score of the variables within the genes. I want to sort my list to have the best scores at the top and the worst at the bottom. It's not doing that, im just so confused here!
|
3

Since java 8 you can sort list of Double elements very simple.

list.sort(Comparator.comparingDouble(Chromosome::getScore));

or

Collections.sort(list, omparator.comparingDouble(Chromosome::getScore));

If you wanna get sorted list but you don't want to change your beginning list you can do it as following:

List<Chromosome> sortedList = list.stream()
     .sorted(Comparator.comparingDouble(A::getScore))
     .collect(Collectors.toList()); 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.