java.lang.IllegalArgumentException: Comparison method violates its general contract!异常分析及解决办法

直接调用Collections的sort:

Collections.sort(keywordList);

出现了如下错误:

Exception in thread “main” java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:744)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:481)
at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:406)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:213)
at java.util.Arrays.sort(Arrays.java:1312)
at java.util.Arrays.sort(Arrays.java:1506)
at java.util.ArrayList.sort(ArrayList.java:1462)
at java.util.Collections.sort(Collections.java:141)
at Tools.TFIDF.analyze(TFIDF.java:42)
at Tools.TFIDF.main(TFIDF.java:169)

这是因为在 JDK7 版本以上,Comparator 要满足自反性,传递性,对称性,否则 Arrays.sort,Collections.sort都会报 IllegalArgumentException 异常。

自反性:当两个相同的元素相比时,compare必须返回0,也就compare(o1, o1) = 0;
反对称性:如果compare(o1,o2) = 1,则compare(o2, o1)必须返回符号相反的值也就是 -1;
传递性:如果 a>b, b>c, 则 a必然大于c。也就是compare(a,b)>0,compare(b,c)>0, 则compare(a,c)>0。

简单来说,就是需要考虑对象o1和对象o2为null的情况,即当o1与o2都为null时两者大小如何判定呢,当o1为null但o2不为null时两者大小又如何判定呢,同理当o2为null但o1不为null时两者大小又如何判定呢。

pdfbox在读pdf文件时,会把null读取下来,你可以在读pdf时就把null去掉,保证排序时不会出现null的情况,但稳妥起见,还是应该在排序时把可能的情况考虑到,并作出相对应的处理。

处理如下,我们重写compare:

List<Keyword> keywordList = new ArrayList<>();
...
Collections.sort(keywordList, new Comparator<Keyword>() {
    @Override
    public int compare(Keyword o1, Keyword o2) {
        if (o1 == null && o2 == null) {
            return 0;
        }
        if (o1 == null) {
            return -1;
        }
        if (o2 == null) {
            return 1;
        }
        return 0;
    }
});

参考:
1、“Comparison method violates its general contract!”问题原因及解决办法
2、Comparison method violates its general contract!

你可能感兴趣的:(Java,java)