关于Comparator的使用细节

Cmparator比较器将集合中的元素两两比较,参数列表o1代表前者,o2代表后者.
比较的依据是两者的权重.权重大的向后排.而权重大小的制定规则可通过逻辑代码自定义.
返回值有三种情况:0,正,负
返回值为正: 前者(也就是o1)权重大,o1向后排
返回值为负: 后者(也就是o2)权重大,o2向后排
返回值为0: 权重相等,不交换

我们常用的写法 例如:

 public int compare(TxtLog o1, TxtLog o2) {
                return o1.getTs() - o2.getTs();
            }

如果o1 > o2,返回值为正,前者(o1)权重大.
如果o2 > o1,返回值为负,后者(o2)权重大.
意思其实就是"两数中较大的一方权重大",权重大往后排,所以排序规则就是升序.

 public int compare(TxtLog o1, TxtLog o2) {
                return o2.getTs() - o1.getTs();
            }

如果o2 > o1,返回值为正,前者(o1)权重大.
如果o1 > o2,返回值为负,后者(o2)权重大.
意思其实就是"两数中较小的一方权重大",权重大往后排,所以排序规则就是降序.

如果排序规则很复杂,则需要另一种写if,else自定义判断条件的写法.一定要将情况考虑全面,各个分支都要想好返回哪种值,否则很可能会出现莫名其妙的排序结果.

在这个过程中可能会遇到这么一个异常:
Exception in thread “main” java.lang.IllegalArgumentException: Comparison method violates its general contract!

造成这个异常一般有三个原因.
1,没有写o1或o2为空时的比较规则
2.没有写两者相等时的排序规则
3.排序规则逻辑不严谨.
Collections.sort()在JDK6和JDK7中实现的底层排序算法变了,在JDK6中使用的时MergeSort排序,而在JDK7中使用的是TimSort。TimSort排序算法对比较大小的要求更高,要满足以下三个特性:
1) 自反性:x,y 的比较结果和 y,x 的比较结果相反。
2) 传递性:x>y,y>z,则 x>z。
3) 对称性:x=y,则 x,z 比较结果和 y,z 比较结果相同。

排序规则很复杂时很可能会考虑不周全,从而违反其中的某一个特性.在不知道返回什么值的时候可以先尽量返回0,然后根据结果更改自己的逻辑代码.

除了改比较函数,还有一个解决方式是:给jvm添加启动参数。
System.setProperty(“java.util.Arrays.useLegacyMergeSort”, “true”);
把排序规则改回去,很可能异常就消失了.

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值