我有一个名为project
的对象,我希望按其两个字段对该项目进行排序:
第一:按日期(格里高利卡兰德); 第二:按名称(字符串);
我想按日期从新到旧的方式对项目进行排序。我知道这样做的唯一方法是撤消收集。但是我想在名称上按字母顺序对项目进行排序,其中反向也会反转这一部分。
有没有办法只反转部分sort方法,或任何其他方式首先按日期(反向)然后字符串(正常顺序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);
}
答案 0 :(得分:3)
在Java 8中,Comparator
接口有一个方法thenComparing
。您可以使用此方法创建一个比较器,该比较器可以通过多个字段进行比较。
如果你有一个比较器按字母顺序比较,而另一个比较器按日期比较,你可以组合比较器按你想要的字段排序:
Comparator<Project> nameComparator = ...
Comparator<Project> dateComparator = ...
如果需要,您可以使用反向比较器混合比较器。这些是一些例子:
Comparator<Project> nameAndDateComparator = nameComparator.thenComparing(dateComparator);
Comparator<Project> nameAndReversedDateComparator = nameComparator.thenComparing(dateComparator.reversed());
然后,您可以像往常一样使用符合您需要的比较器进行排序。
如果您不使用Java 8,则可以创建一个实用程序类来组合比较器:
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));
答案 1 :(得分:2)
Date#compareTo
返回一个值&lt;如果此Date在Date参数之前且值> gt,则为0;否则为0。
如果要将排序从新旧转换为旧,您只需返回否定比较结果:
@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);
}