まず第一に、これは質問Partial Ordered Comparatorの複製ではなく、それに基づいています。
私の目標は、オブジェクトのリスト ([2, "a", 1] など) をその場で並べ替えて、並べ替え後に 2 つの整数の順序が乱れないようにすることです。
このために、この回答の実装を次の半順序で使用し、次の結果を得ましたIllegalArgumentException
。
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:868)
at java.util.TimSort.mergeAt(TimSort.java:485)
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)
at MySortUtils.sortPartially(ArimsCollectionUtils.java:150)
これは、提案されたコンパレータに欠陥があるためです。デモンストレーション:
iffとが両方とも整数であり、整数の自然な順序付けに従っているR
すべてのObject
インスタンスに対して半順序付けを使用します。a.before(b)
a
b
a < b
public boolean before(Object a, Object b) {
// only integers are ordered
if (a instanceof Integer && b instanceof Integer) {
int intA = ((Integer) a).intValue();
int intB = ((Integer) b).intValue();
return intA < intB;
} else {
return false;
}
}
この理由は、次の実装では
Comparator<Object> fullCmp = new Comparator<Object>() {
// Implementation shamelessly plucked from
// https://stackoverflow.com/a/16702332/484293
@Override
public int compare(Object o1, Object o2) {
if(o1.equals(o2)) {
return 0;
}
if(partialComparator.before(o1, o2)) {
return -1;
}
if(partialComparator.before(o2, o1)) {
return +1;
}
return getIndex(o1) - getIndex(o2);
}
private Map<Object ,Integer> indexMap = new HashMap<>();
private int getIndex(Object i) {
Integer result = indexMap.get(i);
if (result == null) {
indexMap.put(i, result = indexMap.size());
}
return result;
}
};
これにより、生成された順序でサイクルが発生する可能性があります。
// since 2 and "a" are incomparable,
// 2 gets stored with index 0
// "a" with index 1
assert fullCmp.compare(2, "a") == -1
// since "a" and 1 are incomparable,
// "a" keeps its index 1
// 2 gets index 2
assert fullCmp.compare("a", 1) == -1
// since 1 and 2 are comparable:
assert fullCmp.compare(1, 2) == -1
つまり、2 < "a"、"a" < 1、"1 < 2 です。これは明らかに有効な全順序付けではありません。
最後の質問は次のとおりです。このバグを修正するにはどうすればよいですか?