使用2个条件在Java中对列表进行排序

Krt*_*lta 13 java sorting

我有一个对象列表.每个对象包含a String和a Date(以及其他对象).

我想首先按顺序排序String,然后按顺序排序Date.

怎么可能以最干净的方式完成?

谢谢!

Krt_Malta

Luk*_*der 20

使用Java 8,这非常简单.特定

class MyClass {
    String getString() { ... }
    Date getDate() { ... }
}
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式轻松对列表进行排序:

List<MyClass> list = ...
list.sort(Comparator.comparing(MyClass::getString).thenComparing(MyClass::getDate));
Run Code Online (Sandbox Code Playgroud)

  • 这个答案应该越来越高 (2认同)

小智 18

给定一个如下所示的对象类:

public class MyObject {
    public String getString() { ... }
    public Date getDate() { ... }
    ...
}
Run Code Online (Sandbox Code Playgroud)

编写自定义比较器类,如下所示:

public class ObjectComparator implements Comparator{

    public int compare(Object obj1, Object obj2) {
        MyObject myObj1 = (MyObject)obj1;
        MyObject myObj2 = (MyObject)obj2;
        stringResult = myObj1.getString().compareTo(myObj2.getString());
        if (stringResult == 0) {
            // Strings are equal, sort by date
            return myObj1.getDate().compareTo(myObj2.getDate());
        }
        else {
            return stringResult;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后排序如下:

Collections.sort(objectList, new ObjectComparator());
Run Code Online (Sandbox Code Playgroud)

  • @Krt_Malta最明确的一个?我不这么认为.首先,它使用了1.5之前的非通用版本的比较器,它更加冗长,容易出错.例如,I82的答案要好得多. (2认同)

Sea*_*oyd 8

Comparator使用compare(a,b)如下方法实现自定义:

普通Java:

 public int compare(YourObject o1, YourObject o2) {
    int result = o1.getProperty1().compareTo(o2.getProperty1()));
    if(result==0) result = o1.getProperty2().compareTo(o2.getProperty2());
    return result;
 }
Run Code Online (Sandbox Code Playgroud)

使用番石榴(使用ComparisonChain):

public int compare(YourObject o1, YourObject o2) {
    return ComparisonChain.start()
      .compare(o1.getProperty1(), o2.getProperty1())
      .compare(o1.getProperty2(), o2.getProperty2())
      .result();
 }
Run Code Online (Sandbox Code Playgroud)

使用Commons/Lang(使用CompareToBuilder):

public int compare(YourObject o1, YourObject o2) {
    return new CompareToBuilder()
      .append(o1.getProperty1(), o2.getProperty1())
      .append(o1.getProperty2(), o2.getProperty2())
      .toComparison();
 }
Run Code Online (Sandbox Code Playgroud)

(所有三个版本相当,但普通的Java版本是最详细的,因此最容易出错的.所有这三个解决方案假定这两个o1.getProperty1()o1.getProperty2()实施Comparable).

(取自我此前的答案)


现在呢 Collections.sort(yourList, yourComparator)


I82*_*uch 7

比较器的答案是正确但不完整的.

StringAndDateComparator implements Comparator<MyObject> {

   public int compare(MyObject first, MyObject second) {
        int result = first.getString().compareTo(second.getString());
        if (result != 0) {
            return result;
        }
        else {
            return first.getDate().compareTo(second.getDate());
        }
}
Run Code Online (Sandbox Code Playgroud)

GlazedLists有一个很好的实用方法,可以将不同的比较器链接在一起,以免您编写此样板文件.有关更多信息,请参阅chainComparators方法.


小智 5

可以使用 2 个 lambda 表达式对简单数组进行排序,如下所示:

Arrays.sort(arr, (i, j) -> (i[0] == j[0] ? j[1] - i[1] : i[0] - j[0]));
Run Code Online (Sandbox Code Playgroud)

表示二维数组arr中的两个子数组 i 和 j将根据数组的第 0 个索引按升序排序。如果第 0 个索引相等,则基于第 1 个索引。