Как отсортировать список объектов по дате (java collection, List <Object>) - PullRequest
17 голосов
/ 06 марта 2011
private List<Movie> movieItems = null;
public List<Movie> getMovieItems() {
    final int first = 0;
    if (movieItems == null) {
        getPagingInfo();
        movieItems = jpaController.findRange(new int[]{pagingInfo.getFirstItem(), pagingInfo.getFirstItem() + pagingInfo.getBatchSize()});
        Collections.sort(movieItems, new Comparator(){
           public int compare (Object o1, Object o2){
               Date d1 = movieItems.get(((Movie)o1).getMovieId()).getDate();
               Date d2 = movieItems.get(((Movie)o2).getMovieId()).getDate();
               if(d1.before(d2)){
                   movieItems.set(1, (Movie)o1);
                   movieItems.set(2, (Movie)o2);
               }
               return first;
           }
       });
    }
    return movieItems;
}

jpaController возвращает 4 фильма и дает мне следующее

java.lang.ArrayIndexOutOfBoundsException: Индекс массива вне диапазона: 4 в java.util.Vector.get (Vector.java: 694) в entitybeans.jsf.PeliculaController $ 1.compare (PeliculaController.java:260) в java.util.Arrays.mergeSort (Arrays.java:1270) в java.util.Arrays.sort (Arrays.java:1210) в java.util.Collections.sort (Collections.java:159) в entitybeans.jsf.PeliculaController.getPeliculaItems (PeliculaController.java:257) в sun.reflect.NativeMethodAccessorImpl.inccess.invoke.No.invoke (NativeMethodAccessorImpl.java:39) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.reflect.Method.invoke (Method.java:59olver.weal.Reval.Real..java: 302) на javax.el.CompositeELResolver.getValue (CompositeELResolver.java:175) на com.sun.faces.el.FacesCompositeELResolver.getValue (FacesCompos)iteELResolver.java:72) на com.sun.el.parser.AstValue.getValue (AstValue.java:116) на com.sun.el.parser.AstValue.getValue (AstValue.java:163) ....

Ответы [ 7 ]

55 голосов
/ 06 марта 2011

В вашем методе compare, o1 и o2 уже являются элементами в списке movieItems. Итак, вы должны сделать что-то вроде этого:

Collections.sort(movieItems, new Comparator<Movie>() {
    public int compare(Movie m1, Movie m2) {
        return m1.getDate().compareTo(m2.getDate());
    }
});
20 голосов
/ 06 марта 2011

Не открывайте и не изменяйте коллекцию в Comparator.Компаратор следует использовать только для определения того, какой объект стоит перед другим.Два объекта, которые должны сравниваться, предоставляются в качестве аргументов.

Date сам по себе сопоставим, поэтому, используя обобщенные значения:

class MovieComparator implements Comparator<Movie> {
    public int compare(Movie m1, Movie m2) {
       //possibly check for nulls to avoid NullPointerException
       return m1.getDate().compareTo(m2.getDate());
    }
}

И не создавайте экземпляр компаратора для каждого вида.Использование:

private static final MovieComparator comparator = new MovieComparator();
16 голосов
/ 29 июля 2016

В Java 8 теперь все просто:

movieItems.sort(Comparator.comparing(Movie::getDate));
15 голосов
/ 06 марта 2011

Вы используете Comparators неправильно.

 Collections.sort(movieItems, new Comparator<Movie>(){
           public int compare (Movie m1, Movie m2){
               return m1.getDate().compareTo(m2.getDate());
           }
       });
1 голос
/ 24 января 2012

Вместо этого я бы добавил Commons NullComparator, чтобы избежать некоторых проблем ...

0 голосов
/ 11 января 2019

Используя функциональность Java 8, это будет проще.

синтаксис : LIST_NAME.sort (Comparator.comparing (INFO_CLASS :: getMethod));

пример : movieItems.sort (Comparator.comparing (видео :: GetDate));

0 голосов
/ 25 марта 2015

Вы можете использовать это:

Collections.sort(list, org.joda.time.DateTimeComparator.getInstance());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...