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
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());
Comments
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
Michael Brewer-Davis
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/…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
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
Hovercraft Full Of Eels
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.