私は、ストリームのソート方法でソートすること(MyDetailオブジェクト)項目のリストを持っています。フィールド1、フィールド2、フィールド3:オブジェクトは、3つのフィールドがあります。私はすべて逆の順序で、フィールド1フィールド2その後、最初にフィールド3でソートしたいです。だから私はこの方法sortMyListを書きました。
、偽、偽myDetail2 "20180201": "20180101"、偽、偽myDetail3:myDetail1:私は以下のようにソートされていない項目のunSortedDetailsのリストを持っている "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;
}
}
あなたのコンパレータといくつかの問題があります。まず、あなたが呼び出すたびということであるreversed()
あなたが反転しているすべてのコンパレータの前の設定を。
あなたのコンパレータが表すように、(コメントの手順を参照してください、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())
。
次の問題は、コンパレータで使用されるフィールドの順序です。あなたの質問では、言いました:
私は、フィールド1フィールド2、その後最初にフィールド3でソートしたいです
しかし、あなたのコンパレータを最初にチェックフィールド1、(そのためには、あなたが経由でそれらを追加しましたので、その後、その後、フィールド2、フィールド3 .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
。