4

Here is my problem, I have a LinkedList of objects, which have a String name and an int score value.

Now, I need to sort this list in descending order based on the score value.

How do I do that? I tried with Collections.sort(List), but that doesn't work with objects.

How do I tell Java to use the score as the value to comparison?

0xCursor
  • 2,242
  • 4
  • 15
  • 33
John
  • 51
  • 1
  • 3
  • Do you mean you have a ```LinkedHashMap```? LinkedList doesn't have K, V pairs. – Siddhartha Oct 17 '15 at 18:33
  • 1
    Collections.sort has a version where you can pass comparator. http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator) – Bartosz Przybylski Oct 17 '15 at 18:34
  • I don't (?) This will be my first time sorting a List, as previously I was using Arrays, so I'm a newbe. Highschool senior, if that gives any reference how much I know about Java – John Oct 17 '15 at 18:37
  • Make sure you understand the distinction between ```List```, ```Map``` and ```Set```. What you described is a ```Map```, which contains a *Key* (String name) and a corresponding *Value* (int score). – Siddhartha Oct 17 '15 at 18:38
  • @Siddhartha IMO he understand it he has something like `LinkedList` where `TeamDescription` is a class with `String` and `int` – Bartosz Przybylski Oct 17 '15 at 18:39
  • @Siddhartha it could be List of custom objects, we don't know that. He did not show any code. I am guessing from this `LinkedList of objects, which have a String name and a int score value.` – YoungHobbit Oct 17 '15 at 18:40
  • Ah I stand corrected. – Siddhartha Oct 17 '15 at 18:41
  • ^this. My list looks like this:`LinkedList DopplerList` – John Oct 17 '15 at 18:42

3 Answers3

9

The Collections.sort method accepts a comparator as its second argument. You can pass in a comparator that defines the ordering that you want. For example given a Person class:

class Person {
    private final String name;
    private final int score;

    Person(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}

You can use Collections.sort with a custom comparator to sort Persons by descending order of score like this:

List<Person> list = new LinkedList<>(Arrays.asList(new Person("Jack", 3), new Person("Mike", 9)));

System.out.println("before: " + list);

Collections.sort(list, new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
        return o2.score - o1.score;
    }
});

System.out.println("after: " + list);

This will output:

before: [Person{name='Jack', score=3}, Person{name='Mike', score=9}]
after: [Person{name='Mike', score=9}, Person{name='Jack', score=3}]
janos
  • 120,954
  • 29
  • 226
  • 236
3

Along with other answers, here is a neat Java 8 solution:

Collections.sort(list, Comparator.comparingInt(obj -> obj.score).reversed());

The reversed() is for descending order, and this compares by obj.score.

As noted by Iaune, obj -> obj.score can be replaced by ObjType::getScore if you are using Encapsulation correctly.

bcsb1001
  • 2,834
  • 3
  • 24
  • 35
  • 1
    Perhaps either obj.getScore() or WhateverTheClassIsCalled::getScore, assuming that the fields aren't public - they shouldn't be ;-). +1 for this neat definition. – laune Oct 17 '15 at 18:49
  • @Downvoter, please leave a comment explaining the issue with my answer so I can fix it. – bcsb1001 Oct 17 '15 at 20:40
  • Not me, but see my comment. – laune Oct 18 '15 at 04:18
0

Collections.sort(List) works for Objects as long as Objects are comparable to one another either through java.lang.Comparable or java.util.Comparator.Since your Objects need custom sorting,you need to implement a comparator

Collections.sort(list,new Comparator(){
    @Override
    public int compare(MyObject obj1,MyObject obj2){
        return obj2.score - obj1.score;
    }
});
Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35