I have a class named Person
with multiple properties, for example:
public class Person { private int id; private String name, address; // Many more properties. }
A lot of Person
-objects are stored in an ArrayList<Person>
. I want to sort this list by multiple sort parameters, and different from time to time. For instance I might one time want to sort by name
ascending and then address
descending, and another time just by id
descending.
And I don't want to create my own sort methods (i.e., I want to use Collections.sort(personList, someComparator)
. What is the most elegant solution that achieves this?
The sort() method sorts the list in ascending order, according to the natural ordering of its elements. The signature of the method is: public static <T extends Comparable<? Super T>> void sort() (List<T> list)
sort() method to sort a list of objects using some examples. By default, the sort() method sorts a given list into ascending order (or natural order). We can use Collections. reverseOrder() method, which returns a Comparator, for reverse sorting.
In the main() method, we've created an array list of custom objects list , initialized with 5 objects. For sorting the list with the given property, we use list 's sort() method. The sort() method takes the list to be sorted (final sorted list is also the same) and a comparator .
We can simply implement Comparator without affecting the original User-defined class. To sort an ArrayList using Comparator we need to override the compare() method provided by comparator interface. After rewriting the compare() method we need to call collections. sort() method like below.
I think your enum approach is basically sound, but the switch statements really need a more object oriented approach. Consider:
enum PersonComparator implements Comparator<Person> { ID_SORT { public int compare(Person o1, Person o2) { return Integer.valueOf(o1.getId()).compareTo(o2.getId()); }}, NAME_SORT { public int compare(Person o1, Person o2) { return o1.getFullName().compareTo(o2.getFullName()); }}; public static Comparator<Person> decending(final Comparator<Person> other) { return new Comparator<Person>() { public int compare(Person o1, Person o2) { return -1 * other.compare(o1, o2); } }; } public static Comparator<Person> getComparator(final PersonComparator... multipleOptions) { return new Comparator<Person>() { public int compare(Person o1, Person o2) { for (PersonComparator option : multipleOptions) { int result = option.compare(o1, o2); if (result != 0) { return result; } } return 0; } }; } }
An example of usage (with a static import).
public static void main(String[] args) { List<Person> list = null; Collections.sort(list, decending(getComparator(NAME_SORT, ID_SORT))); }
You can create comparators for each of properties you might want to sort and then try "comparator chaining" :-) like this:
public class ChainedComparator<T> implements Comparator<T> { private List<Comparator<T>> simpleComparators; public ChainedComparator(Comparator<T>... simpleComparators) { this.simpleComparators = Arrays.asList(simpleComparators); } public int compare(T o1, T o2) { for (Comparator<T> comparator : simpleComparators) { int result = comparator.compare(o1, o2); if (result != 0) { return result; } } return 0; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With