こんにちは、私のコンパレータの比較方法です。何が悪いのか分かりません。私はスタックオーバーフローに関する他の同様のタイトルの質問と回答を調べましたが、私のメソッドの何が間違っているのかわかりませんが、Java.lang.IllegalArgumentExceptionを取得し続けています:比較メソッドはその一般的な契約に違反しています!
どんな助けも大歓迎です
public int compare(Node o1, Node o2)
{
HashMap<Integer,Integer> childMap = orderMap.get(parentID);
if(childMap != null && childMap.containsKey(o1.getID()) &&
childMap.containsKey(o2.getID()))
{
int order1 = childMap.get(o1.getID());
int order2 = childMap.get(o2.getID());
if(order1<order2)
return -1;
else if(order1>order2)
return 1;
else
return 0;
}
else
return 0;
}
私が得ている例外を追加する
Java.lang.IllegalArgumentException: Comparison method violates its general contract!
at Java.util.TimSort.mergeLo(TimSort.Java:747)
at Java.util.TimSort.mergeAt(TimSort.Java:483)
at Java.util.TimSort.mergeCollapse(TimSort.Java:410)
at Java.util.TimSort.sort(TimSort.Java:214)
at Java.util.TimSort.sort(TimSort.Java:173)
at Java.util.Arrays.sort(Arrays.Java:659)
at Java.util.Collections.sort(Collections.Java:217)
compare()
メソッドはnottransitiveです。 A == B
およびB == C
の場合、A
はC
と等しくなければなりません。
次に、このケースを検討します。
A
、B
、およびC
の場合、containsKey()
メソッドがこれらの結果を返すと仮定します。
childMap.containsKey(A.getID())
はtrue
を返しますchildMap.containsKey(B.getID())
はfalse
を返しますchildMap.containsKey(C.getID())
はtrue
を返しますまた、A.getId()
!= B.getId()
の注文を検討してください。
そう、
A
とB
は0
を返します。外側のif
条件はfalse
=> A == B
になるためですB
とC
は0
を返します。外側のif
条件はfalse
=> B == C
になるためですただし、A
およびC
は、if
ブロック内のテストに基づいて、-1
または1
を返す可能性があります。したがって、A != C
。これは、推移性の原則に違反しています。
else
ブロック内に何らかの条件を追加して、if
ブロックで行うのと同様のチェックを実行する必要があると思います。
問題はデフォルトの場合だと思います。 IDが'a'
、'b'
、および'c'
であるノードA、B、およびCのセットを考えます。さらに、相対的な注文情報を含むchildMap
の内容が次のとおりであることを考慮してください。
{ 'a' => 1, 'c' => 3 }
compare
メソッドをAとBで実行すると、0
が返され、AとBが同等であることを示します。さらに、BとCを比較しても、0
を返します。ただし、AとCを比較すると、-1
を返し、Aが小さいことを示します。これは Comparator
契約 の推移性プロパティに違反します。
実装者は、関係が推移的であることも確認する必要があります。
((compare(x, y)>0) && (compare(y, z)>0))
はcompare(x, z)>0
を意味します。最後に、実装者は、すべての
z
に対してcompare(x, y)==0
がsgn(compare(x, z))==sgn(compare(y, z))
を意味することを確認する必要があります。
「順序が割り当てられていないアイテム」は、値が「漠然と中間にある」として扱うことはできません。ソートアルゴリズムはそれらをどこに置くかわからないからです。このアプローチを維持したい場合、値がマップに存在しない場合は、順序値となる固定値を割り当てる必要があります。 0
またはMIN_INT
のようなものが妥当な選択です(ただし、compare
!については、Javadocですべての選択を文書化する必要があります)。