从自定义对象中反转部分 CompareTo 方法

Reversing part of the CompareTo method from custom objects

我有一个名为 project 的对象,我想按其中的 2 个字段对这个项目进行排序:

首先:按日期(Gregorian Callander); 第二:按名称(字符串);

我想按日期从新到旧对项目进行排序。我知道这样做的唯一方法是反转集合。但是我想对名称上具有相同日期的项目进行排序(按字母顺序),其中 reverse 也会反转这部分排序。

有没有办法只反转排序方法的一部分,或者有任何其他方法首先按日期(反转)然后按字符串(正常顺序 a-z)排序?

目前我正在覆盖对象 compareTo 方法,如下所示:

   @Override
public int compareTo(Project project) {
    int i = this.projectDate.compareTo(project.projectDate);
    if(i != 0) return i;

    return this.projectName.compareTo(project.projectName);

}

Date#compareTo return如果此日期在日期参数之前,则值为 < 0,否则值为 > 0。

如果你想从新到旧反转排序,你可以return否定比较结果:

@Override
public int compareTo(Project project) {
    int i = this.projectDate.compareTo(project.projectDate);
    if(i != 0) return -i;  // reverse sort

    return this.projectName.compareTo(project.projectName);
}

在Java8中,Comparator接口有一个方法thenComparing。您可以使用此方法创建一个比较多个字段的比较器。

如果您有一个按字母顺序比较的比较器和另一个按日期比较的比较器,您可以组合比较器以按您想要的字段排序:

Comparator<Project> nameComparator = ...
Comparator<Project> dateComparator = ...

您可以混合使用比较器,如果需要可以使用反向比较器。这些是一些例子:

Comparator<Project> nameAndDateComparator = nameComparator.thenComparing(dateComparator);
Comparator<Project> nameAndReversedDateComparator = nameComparator.thenComparing(dateComparator.reversed());

然后,您可以像往常一样使用符合您需要的比较器的方法排序。

如果您没有使用 Java 8,您可以创建一个实用程序 class 来组合您的比较器:

public class CombinedComparator<T> implements Comparator<T> {

    Comparator<T> firstComparator;
    Comparator<T> secondComparator;

    public CombinedComparator(Comparator<T> firstComparator, Comparator<T> secondComparator) {
        this.firstComparator = firstComparator;
        this.secondComparator = secondComparator;
    }

    @Override
    public int compare(T o1, T o2) {
        int result = firstComparator.compare(o1, o2);
        return (result != 0) ? result : secondComparator.compare(o1, o2);
    }

}

您可以通过这种方式创建多个字段比较器:

Comparator<Project> nameAndDateComparator = new CombinedComparator<Project>(nameComparator, dateComparator);

Comparator<Project> nameAndReversedDateComparator = new CombinedComparator<Project>(nameComparator, Collections.reverseOrder(dateComparator));