Saturday 23 January 2016

java - Sort ArrayList of custom Objects by property



I read about sorting ArrayLists using a Comparator but in all of the examples people used compareTo which according to some research is a method for Strings.



I wanted to sort an ArrayList of custom objects by one of their properties: a Date object
(getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like:




public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}

public class RandomName {
...
Collections.sort(Database.arrayList, new CustomComparator);
...

}

Answer



Since Date implements Comparable, it has a compareTo method just like String does.



So your custom Comparator could look like this:



public class CustomComparator implements Comparator {
@Override
public int compare(MyObject o1, MyObject o2) {

return o1.getStartDate().compareTo(o2.getStartDate());
}
}


The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.



Your sorting code would be just about like you wrote:



Collections.sort(Database.arrayList, new CustomComparator());



A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:



Collections.sort(Database.arrayList, new Comparator() {
@Override
public int compare(MyObject o1, MyObject o2) {
return o1.getStartDate().compareTo(o2.getStartDate());
}
});








You can now write the last example in a shorter form by using a lambda expression for the Comparator:



Collections.sort(Database.arrayList, 
(o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));



And List has a sort(Comparator) method, so you can shorten this even further:



Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));


This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:



Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));



All of these are equivalent forms.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...