我有一个要使用流排序方法排序的项目列表(MyDetail对象)。该对象具有3个字段:field1,field2,field3。 我想先按field3排序,然后按field2再按field1排序,所有顺序都相反。 所以我写了一个方法sortMyList。
我有一个未排序项目unSortedDetails的列表,如下所示: myDetail1:“ 20180201”,错误,错误 myDetail2:“ 20180101”,错误,错误 myDetail3:“ 20180101”,错误,正确
sortMyList(unSortedDetails)之后,我希望我的结果是myDetail3,myDetail1,myDetail2,但实际结果是myDetail1,myDetail3,myDetail2,为什么?
因此,如果我像以下那样实现MyDetail的Comparable,那么它将按预期工作。这太奇怪了。我不知道为什么。谢谢你的帮助!
public List<MyDetail> sortMyList(List<MyDetail> unSortedDetails){
List<MyDetail> myDetails = unSortedDetails
.stream().sorted(Comparator.comparing(MyDetail::getField11).reversed()
.thenComparing(MyDetail::getField2).reversed()
.thenComparing(MyDetail::getField3).reversed())
.collect(Collectors.toList());
return myDetails;
}
@Setter
@Getter
public class MyDetail{
String field1;
Boolean field2;
Boolean field3;
}
@Setter
@Getter
public class MyDetail implement Comparable<MyDetail>{
String field1;
Boolean field2;
Boolean field3;
@Override
public int compareTo(MyDetail o) {
if (this == o || this.equals(o)) return 0;
if (field3) return -1;
if (o.field3) return 1;
if (!field3 && !o.field3 && field2) return -1;
if(!field3 && !o.field3 &&!field2 && o.field2) return 1;
if(!field3 && !o.field3
&&!field2 && !o.field2){
return o.field1.compareTo(field1);
}
return 0;
}
}
答案 0 :(得分:6)
比较器几乎没有问题。首先,每次调用reversed()
时,您都将反转比较器的 all 先前的所有设置。
所以您的比较器代表了(请参见注释中的步骤,FieldX
简化为Fx
)
Comparator.comparing(MyDetail::getField11) // F1 ASC
.reversed() //~(F1 ASC)
// F1 DESC
.thenComparing(MyDetail::getField2) // F1 DESC, F2 ASC
.reversed() //~(F1 DESC, F2 ASC)
// F1 ASC, F2 DESC
.thenComparing(MyDetail::getField3) // F1 ASC, F2 DESC, F3 ASC
.reversed() //~(F1 ASC, F2 DESC, F3 ASC)
// F1 DESC, F2 ASC, F3 DESC
所以您最终得到订单Field1 DESC, Field2 ASC, Field3 DESC
。
要为每个字段指定颠倒顺序,请通过 传递该字段已经颠倒的比较器 ,例如.thenComparing(Comparator.comparing(YourClass::getField).reversed())
。
下一个问题是比较器使用的字段顺序。在您的问题中,您说:
我想先按field3排序,然后按field2排序,然后按field1排序
但是您的比较器首先检查field1,然后检查field2,然后检查field3(因为您是通过.thenComparing
依次添加的)。
您的代码应该更像
Comparator.comparing(MyDetail::getField13).reversed()
.thenComparing(Comparator.comparing(MyDetail::getField2).reversed())
.thenComparing(Comparator.comparing(MyDetail::getField1).reversed())
因此,您正在创建~(F3 ASC), ~(F2 ASC), ~(F1 ASC)
,结果为F3 DESC, F2 DESC, F1 DESC
。
Comparator.comparing(MyDetail::getField3)
.thenComparing(MyDetail::getField2)
.thenComparing(MyDetail::getField1)
.reversed()
请注意,Comparaor.comparing(FunctionToValue)
和thenComparing(FunctionToValue)
将为选定的值创建升序比较器。
因此,前3行构造了比较器,描述了顺序F3 ASC, F2 ASC, F1 ASC
。反转后
~(F3 ASC, F2 ASC, F1 ASC)
也给了我们想要的F3 DESC, F2 DESC, F1 DESC
。