直接调用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!