按照多个属性对ArrayList进行排序

17
我有一个对象的ArrayList。该对象包含属性“date”和“value”。因此,我想按照“date”对对象进行排序,并且对于所有在相同日期的对象,我想按照“value”对它们进行排序。我该怎么做?

我有一个包含对象的ArrayList。每个对象都包含“date”和“value”属性。所以,我想按照“date”对这些对象进行排序,对于所有在同一日期的对象,我想按照“value”对它们进行排序。如何实现?

5个回答

23

实现一个自定义的Comparator,然后使用Collections.sort(List, Comparator)。代码可能会像下面这样:

public class FooComparator implements Comparator<Foo> {
    public int compare(Foo a, Foo b) {
        int dateComparison = a.date.compareTo(b.date);
        return dateComparison == 0 ? a.value.compareTo(b.value) : dateComparison;
    }
}

Collections.sort(foos, new FooComparator());

3
public static <T> void sort(List<T> list, final List<Comparator<T>> comparatorList) {  
       if (comparatorList.isEmpty()) {//Always equals, if no Comparator.  
            throw new IllegalArgumentException("comparatorList is empty.");  
       }  
       Comparator<T> comparator = new Comparator<T>() {  
       public int compare(T o1, T o2) {  
               for (Comparator<T> c:comparatorList) {  
                   if (c.compare(o1, o2) > 0) {  
                     return 1;  
                   } else if (c.compare(o1, o2) < 0) {  
                     return -1;  
                   }  
               }  
               return 0;  
         }  
       };  
       Collections.sort(list, comparator);  
  } 

考虑使用库调用来合并比较器,而不是在此处实现自己的比较器--请参阅Guava的Ordering类:http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Ordering.html - Michael Brewer-Davis

2

使用Stream API的Java-8解决方案:

List<Foo> sorted = list.stream()
                        .sorted(Comparator.comparing(Foo::getDate)
                                        .thenComparing(Foo::getValue))
                        .collect(Collectors.toList());

如果您想对原始的列表进行排序:

list.sort(Comparator.comparing(Foo::getDate)
                    .thenComparing(Foo::getValue)); 

1
如果您想查看示例代码,可以使用以下代码:
Collections.sort(foos, new Comparator<Foo>{
    public int compare(Foo a, Foo b) {
        int dateComparison = a.date.compareTo(b.date);
        return dateComparison == 0 ? a.value.compareTo(b.value) : dateComparison;
    }
});

0
如果对象的类实现了Comparable接口,那么你只需要正确编写compareTo方法来首先比较日期,然后如果日期相等,则比较值,并根据结果返回适当的int值。

如果您不想让类实现Comparable,也可以像上面提到的那样使用Comparator来完成这个操作...这是您的选择。如果您使用Comparator,那么compare方法将会利用我上面的建议。 - Hovercraft Full Of Eels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接