Sort ArrayList of custom Objects by property

2018-12-30 22:34发布

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);
    ...
}

25条回答
浮光初槿花落
2楼-- · 2018-12-30 23:00

You can use the Bean Comparator to sort on any property in your custom class.

查看更多
刘海飞了
3楼-- · 2018-12-30 23:02

Yes, you can. There are two options with comparing items, the Comparable interface, and the Comparator interface.

Both of these interfaces allow for different behavior. Comparable allows you to make the object act like you just described Strings (in fact, String implements Comparable). The second, Comparator, allows you to do what you are asking to do. You would do it like this:

Collections.sort(myArrayList, new MyComparator());

That will cause the Collections.sort method to use your comparator for it's sorting mechanism. If the objects in the ArrayList implement comparable, you can instead do something like this:

Collections.sort(myArrayList);

The Collections class contains a number of these useful, common tools.

查看更多
不流泪的眼
4楼-- · 2018-12-30 23:02
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;

public class test {

public static class Person {
    public String name;
    public int id;
    public Date hireDate;

    public Person(String iname, int iid, Date ihireDate) {
        name = iname;
        id = iid;
        hireDate = ihireDate;
    }

    public String toString() {
        return name + " " + id + " " + hireDate.toString();
    }

    // Comparator
    public static class CompId implements Comparator<Person> {
        @Override
        public int compare(Person arg0, Person arg1) {
            return arg0.id - arg1.id;
        }
    }

    public static class CompDate implements Comparator<Person> {
        private int mod = 1;
        public CompDate(boolean desc) {
            if (desc) mod =-1;
        }
        @Override
        public int compare(Person arg0, Person arg1) {
            return mod*arg0.hireDate.compareTo(arg1.hireDate);
        }
    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
    ArrayList<Person> people;
    people = new ArrayList<Person>();
    try {
        people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
        people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
        people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Collections.sort(people, new Person.CompId());
    System.out.println("BY ID");
    for (Person p : people) {
        System.out.println(p.toString());
    }

    Collections.sort(people, new Person.CompDate(false));
    System.out.println("BY Date asc");
    for (Person p : people) {
        System.out.println(p.toString());
    }
    Collections.sort(people, new Person.CompDate(true));
    System.out.println("BY Date desc");
    for (Person p : people) {
        System.out.println(p.toString());
    }

}

}
查看更多
永恒的永恒
5楼-- · 2018-12-30 23:03

This code snippets might be useful. If you want to sort an Object in my case I want to sort by VolumeName:

public List<Volume> getSortedVolumes() throws SystemException {
    List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
    Collections.sort(volumes, new Comparator<Volume>() {
        public int compare(Volume o1, Volume o2) {
            Volume p1 = (Volume) o1;
            Volume p2 = (Volume) o2;
            return p1.getVolumeName().compareToIgnoreCase(
                    p2.getVolumeName());
        }
    });
    return volumes;
}

This works. I use it in my jsp.

查看更多
查无此人
6楼-- · 2018-12-30 23:03

I prefer this process:

public class SortUtil
{    
    public static <T> List<T> sort(List<T> list, String sortByProperty)
    {
            Collections.sort(list, new BeanComparator(sortByProperty));
            return list;
    }
}

List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");

If you list of objects has a property called startDate, you call use this over and over. You can even chain them startDate.time.

This requires your object to be Comparable which means you need a compareTo, equals, and hashCode implementation.

Yes, it could be faster... But now you don't have to make a new Comparator for each type of sort. If you can save on dev time and give up on runtime, you might go with this one.

查看更多
荒废的爱情
7楼-- · 2018-12-30 23:05

Since technologies appear everyday, the answer will change in the time. I took a look at LambdaJ and seems very interesting.

You can try solving these tasks with LambdaJ. You can find it here: http://code.google.com/p/lambdaj/

Here you have an example:

Sort Iterative

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
        public int compare(Person p1, Person p2) {
           return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
        }
});

Sort with lambda

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

Of course, having this kind of beauty impacts in the performance (an average of 2 times), but can you find a more readable code?

查看更多
登录 后发表回答