Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I sort a list by different parameters at different timed

Tags:

java

sorting

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?

like image 498
runaros Avatar asked Sep 14 '09 12:09

runaros


People also ask

How do you sort a list What does sort method take as parameter?

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)

What are the different ways to sort a list of objects?

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.

How do I sort a list of custom objects?

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 .

How do I sort a list in 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.


2 Answers

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))); } 
like image 196
Yishai Avatar answered Sep 21 '22 17:09

Yishai


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;     } } 
like image 37
Tadeusz Kopec for Ukraine Avatar answered Sep 24 '22 17:09

Tadeusz Kopec for Ukraine