17

I have an ArrayList of object. The object contain attributes date and value. So I want to sort the objects on the date, and for all objects in the same date I want to sort them on value. How can I do that?

5 Answers 5

23

Implement a custom Comparator, then use Collections.sort(List, Comparator). It will probably look something like this:

public class FooComparator implements Comparator<Foo> {
    public int compare(Foo a, Foo b) {
        int dateComparison = a.date.compareTo(b.date);
        return dateComparison == 0 ? a.value.compareTo(b.value) : dateComparison;
    }
}

Collections.sort(foos, new FooComparator());
Sign up to request clarification or add additional context in comments.

Comments

3
public static <T> void sort(List<T> list, final List<Comparator<T>> comparatorList) {  
       if (comparatorList.isEmpty()) {//Always equals, if no Comparator.  
            throw new IllegalArgumentException("comparatorList is empty.");  
       }  
       Comparator<T> comparator = new Comparator<T>() {  
       public int compare(T o1, T o2) {  
               for (Comparator<T> c:comparatorList) {  
                   if (c.compare(o1, o2) > 0) {  
                     return 1;  
                   } else if (c.compare(o1, o2) < 0) {  
                     return -1;  
                   }  
               }  
               return 0;  
         }  
       };  
       Collections.sort(list, comparator);  
  } 

1 Comment

Consider using a library call to merge the comparators instead of implementing your own here--see Guava's Ordering class: guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/…
2

Java-8 solution using Stream API:

List<Foo> sorted = list.stream()
                        .sorted(Comparator.comparing(Foo::getDate)
                                        .thenComparing(Foo::getValue))
                        .collect(Collectors.toList());

If you want to sort the original list itself:

list.sort(Comparator.comparing(Foo::getDate)
                    .thenComparing(Foo::getValue)); 

Comments

1

If you want sample code looks like, you can use following:

Collections.sort(foos, new Comparator<Foo>{
    public int compare(Foo a, Foo b) {
        int dateComparison = a.date.compareTo(b.date);
        return dateComparison == 0 ? a.value.compareTo(b.value) : dateComparison;
    }
});

Comments

0

If the class of the object implements Comparable, then all you need to do is properly code the compareTo method to first compare dates, and then if dates are equal, compare values, and then return the appropriate int result based on the findings.

1 Comment

Or you can do this with a Comparator as noted above if you don't want to make the class implement Comparable.... your choice. If you use a Comparator, then the compare method will utilize my suggestion above.

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.