1. ホーム
  2. ジャワ

比較方式がその一般契約に違反している。

2022-02-21 04:43:58

java.lang.IllegalArgumentException: 比較メソッドが一般契約に違反しています!
    at java.util.TimSort.mergeLo(TimSort.java:777)
    at java.util.TimSort.mergeAt(TimSort.java:514)
    at java.util.TimSort.mergeCollapse(TimSort.java:439)
    java.util.TimSort.sort(TimSort.java:245)にて。
    at java.util.Arrays.sort(Arrays.java:1512)
    at java.util.ArrayList.sort(ArrayList.java:1462)

ソートのバグがあるので調べてみたら、結構高度なことをやっているんですね。

並べ替えたい対象は、対称性、移譲性、自己再帰性を満たすように提案する必要があると書いてあります。正直なところ、それが何なのかわからないんです。 <スパン 問題をどう解決するかが気になる。

私の当初の注文はこのように書かれていました。

    /**
     * Asynchronous transactions are sorted by creation time in descending order
     */
    Ordering<AdaptiveTrace> ADAPTIVE_TRACE_DESC_ORDERING = new Ordering<AdaptiveTrace>() {
        @Override
        public int compare(AdaptiveTrace left, AdaptiveTrace right) {
            if (left == null || left.getCreateAt() == null) {
                return 1;
            }
            if (right == null || right.getCreateAt() == null) {
                return -1;
            }
            return right.getCreateAt().compareTo(left.getCreateAt());
        }
    };

すると、このコードでエラーが報告されます。このデータで同時にヌルヌルを取得しているからだそうです。

次に、これを修正する方法をご覧ください。

    /**
     * Alias scheme in descending order of creation
     */
    Ordering<AliasScheme> ALIAS_SCHEME_DESC_ORDERING = new Ordering<AliasScheme>() {
        @Override
        public int compare(AliasScheme left, AliasScheme right) {
            if (left == null && right == null) {
                return 0;
            }
            if (left == null) {
                return 1;
            }
            if (right == null) {
                return -1;
            }
            if (left.getCreateAt() == null && right.getCreateAt() == null) {
                return 0;
            }
            if (left.getCreateAt() == null) {
                return 1;
            }
            if (right.getCreateAt() == null) {
                return -1;
            }
            return right.getCreateAt().compareTo(left.getCreateAt());
        }
    };

ほら、今回は判定がいい。

では、仕分けはOKなんですね。

そして、ソート・インターフェースが呼び出されるコードは次のようになります。


        List<AliasScheme> aliasSchemes = Lists.newArrayList(aliasSchemeRepository.findAll());
        aliasSchemes.sort(OrderingConstants.ALIAS_SCHEME_DESC_ORDERING);

そして、完成です。