1

I have a List with my own Objects, called OrderedProducts. I want to sort this List first by an int sequence, and then by a String name.

I know how to sort by sequence first, using the following default Collections.sort:

Collections.sort(orderedProductsList, new Comparator<OrderedProduct>(){
    @Override
    public int compare(OrderedProduct op1, OrderedProduct op2){
        if(op1.getSequence() < op2.getSequence())
            return -1;
        else if(op1.getSequence() > op2.getSequence())
            return 1;
        else // op1.getSequence() == op2.getSequence()
            return 0;
    }
});

What I want now is to sort by Name within the ordered Sequence. So, for example, I've got the following OrderedProducts in my List:

  1. Sequence = 2; Name = "AAA";
  2. Sequence = 4; Name = "AAA";
  3. Sequence = 7; Name = "BBB";
  4. Sequence = 2; Name = "CCC";
  5. Sequence = 1; Name = "ZZZ";
  6. Sequence = 4; Name = "ZZZ";
  7. Sequence = 4; Name = "ABC";

This should be sorted like:

5, 1, 4, 2, 7, 6, 3.

Sequence    Name

1           "ZZZ"
2           "AAA"
2           "CCC"
4           "AAA"
4           "ABC"
4           "ZZZ"
7           "BBB"
Kevin Cruijssen
  • 9,153
  • 9
  • 61
  • 135

2 Answers2

1

For that you just need to sort the collection using Collections.sort() by name first, and then when you sort it by the sequence, your collection will be sorted by sequence, and within the sequence, it will be sorted by the name (This is because Collections.sort() is stable).

You can name your compare methods, to have to compare methods, one for sequence and the other for name as shown below:

Taken from this link

public static Comparator < Student > NAME = new Comparator < Student > () {@
    Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
};
public static Comparator < Student > AGE = new Comparator < Student > () {@
    Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
};
Community
  • 1
  • 1
anirudh
  • 4,116
  • 2
  • 20
  • 35
  • Thanks for the answer, but I've decided to go with FuzzyTree's answer (after a small change to his code using the Java's default `String#compareToIgnoreCase` method). – Kevin Cruijssen Jun 02 '14 at 08:19
1

In your comparator, when the sequence is equal compare the name

Collections.sort(orderedProductsList, new Comparator<OrderedProduct>(){
    @Override
    public int compare(OrderedProduct op1, OrderedProduct op2){
        if(op1.getSequence() < op2.getSequence())
            return -1;
        else if(op1.getSequence() > op2.getSequence())
            return 1;
        else 
            return op1.getName().compareToIgnoreCase(op2.getName());            
    }
});
FuzzyTree
  • 32,014
  • 3
  • 54
  • 85
  • 1
    Thanks, accepted as answer. I use `return op1.getName().compareToIgnoreCase(op2.getName());` now within the else, since Names are Strings. – Kevin Cruijssen Jun 02 '14 at 08:20