美文网首页
-Djava.util.Arrays.useLegacyMerg

-Djava.util.Arrays.useLegacyMerg

作者: zh_harry | 来源:发表于2020-12-20 15:32 被阅读0次
    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:408)
    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)
    

    在 JDK7 版本以上,Comparator 要满足自反性,传递性,对称性,不然 Arrays.sort,

    Collections.sort 会报 IllegalArgumentException 异常。

    说明:

    1) 自反性:x,y 的比较结果和 y,x 的比较结果相反。

    2) 传递性:x>y,y>z,则 x>z。

    3) 对称性:x=y,则 x,z 比较结果和 y,z 比较结果相同。

    重现

    package com.sparrow.jdk.collections;
    
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.*;
    
    /**
     * -Djava.util.Arrays.useLegacyMergeSort=true
     */
    public class DictionaryTest {
        public static void main(String[] args) {
            //exception
            int[] array = new int[]{1, 2, 3, 2, 2, 3, 2, 3, 2, 2, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    
            array = new int[]{2, 3, 2, 2, 3, 2, 3, 2, 2, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    
            List<DictionaryEntry> list = new ArrayList<>();
            Set<DictionaryEntry> set = new TreeSet<>();
            for (int i = 0; i < array.length; i++) {
                DictionaryEntry entry = new DictionaryEntry();
                entry.setItemId(i);
                entry.setScore(new BigDecimal(array[i]));
                list.add(entry);
                set.add(entry);
            }
            long current = System.currentTimeMillis();
            for (int i = 0; i < 1000000; i++) {
                //System.out.println(set.size());
                Collections.sort(list);
                //System.out.println(list.size());
            }
            System.out.println(System.currentTimeMillis() - current);
        }
    
        public static class DictionaryEntry implements Comparable<DictionaryEntry> {
            public DictionaryEntry() {
            }
    
            private Integer itemId;
            private BigDecimal score;
    
            public BigDecimal getScore() {
                return score;
            }
    
            public void setScore(BigDecimal score) {
                if (score != null) {
                    this.score = score.setScale(5, RoundingMode.HALF_UP);
                } else {
                    this.score = new BigDecimal(0);
                }
            }
    
            public Integer getItemId() {
                return itemId;
            }
    
            public void setItemId(Integer itemId) {
                this.itemId = itemId;
            }
    
            @Override
            public int compareTo(DictionaryEntry o) {
                //tree set o.score.compareTo(this.score)==0时去重
                //手动设置非0时,throw new IllegalArgumentException("Comparison method violates its general contract!");
                //-Djava.util.Arrays.useLegacyMergeSort=true 解决兼容
                return o.score.compareTo(this.score) == 0 ? -1 : o.score.compareTo(this.score);
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:-Djava.util.Arrays.useLegacyMerg

          本文链接:https://www.haomeiwen.com/subject/eqdknktx.html