Susie
Susie

Reputation: 5128

Sort a list of objects

Is there such a method as follows I can use, so that I can pass any list of any objects and it will return a sorted list in the order I want?

public List sort(List listToBeSorted, String order, String property){ }

class Person{
    private String name;
    private Date dob;
    private int age; 
}

So if I call the above method like so:

sort(myList, "ascending", "name");

It will sort the list in ascending order of "name" property of the person object.


I tried using Comparator as follows but couldn't get it anywhere close to what I actually wanted.

   public class PersonComparator {
    public static final Comparator<Person> NAME_COMPARATOR = new Comparator<Person>() {
        @Override
        public int compare(Person object1, Person object2) {            
            return object1.getName().compareToIgnoreCase(object2.getName());
        }       
    };  
    public static final Comparator<Person> DOB_COMPARATOR = new Comparator<Person>() {
        @Override
        public int compare(Person object1, Person object2) {
            return object1.getDob().compareTo(object2.getDob());
        }       
    };  
    public static final Comparator<Person> AGE_COMPARATOR = new Comparator<Person>() {
        @Override
        public int compare(Person object1, Person object2) {
            return object1.getAge().compareTo(object2.getAge());
        }       
    };  
}

And used the comparator as follows:

List<Person> myList = new ArrayList<Person>();
Collections.sort(myList, PersonComparator.NAME_COMPARATOR);

EDIT:

The example I have given works fine. But It only works for Person class. I wanted a method that would work for any list of objects and I can specify what order I want as well as the property of the object to sort by.

Upvotes: 1

Views: 487

Answers (3)

DarthCoder
DarthCoder

Reputation: 354

You can implement like this ...

class MyCompartor<E>{
    public Comparator<E> getCompartor(final String order,final String propertyName){

        return new Comparator<E>() {

                @Override
                public int compare(E o1, E o2) {
                        Class noparams[]={};
                        try {
                            char temp[] = propertyName.toCharArray();
                            temp[0] = Character.toUpperCase(temp[0]);
                            String tempName=new String(temp);
                            Method method = o1.getClass().getDeclaredMethod("get"+tempName, noparams);
                            Object val1 = method.invoke(o1, null);
                            Object val2 = method.invoke(o2, null);
                            if(order.equalsIgnoreCase("ascending"))
                            {
                                return ((Comparable)val1).compareTo(val2);
                            }else{
                                return ((Comparable)val2).compareTo(val1);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        } 
                    return 0;
                }
            };
    }
}

and calling the sort like this

Collections.sort(list,new MyCompartor<Person>().getCompartor("ascending", "name"));

hope this helps ?? but mind you the property must return an object that is java.lang.Comparable

Upvotes: 1

camickr
camickr

Reputation: 324078

Check out the Bean Comparator.

It will sort the list in ascending order of "name" property of the person object.

You can control the sort order, but you specify a method to access the property, not the property itself.

Upvotes: 3

zw324
zw324

Reputation: 27180

For ascending and descending, you might use reverseOrder to get a different Comparator. That is supported directly by Java, and is a rather standard method for achieving the effect of reversing the ordering.

If you want to use different fields base on a parameter, then you might need reflection to do it. Note you might want to check if the field isAssaignableFrom Comparable before comparing the fields. Otherwise, you could choose to throw an IllegalArgumentException or something close.

Upvotes: 2

Related Questions