java新手的通病_Java新手非常容易犯的一个错误

最近一直在做底层方面的研究,所以这段时间就没写java相关的东西,但恰巧今天同事问我一个问题,在帮他解决完这个问题之后,我发现,这个问题对java新手来说还是非常容易犯的,所以在这里记录下。

首先看下面这段代码:

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ThreadLocalRandom;

public class Test {

public static void main(String[] args) {

List l = new ArrayList<>();

for (int i = 0; i < 100000; i++) {

l.add(ThreadLocalRandom.current().nextLong());

}

l.sort((o1, o2) -> (int) (o1 - o2));

// l.sort(Long::compare);

}

}

这段代码的功能就是对list进行排序,list内元素类型是long。

一眼看上去好像没啥大问题,执行看下:

Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!

at java.base/java.util.TimSort.mergeLo(TimSort.java:781)

at java.base/java.util.TimSort.mergeAt(TimSort.java:518)

at java.base/java.util.TimSort.mergeCollapse(TimSort.java:448)

at java.base/java.util.TimSort.sort(TimSort.java:245)

at java.base/java.util.Arrays.sort(Arrays.java:1516)

at java.base/java.util.ArrayList.sort(ArrayList.java:1749)

at io.ytcode.game.test/test.Test.main(Test.java:14)

额,报错了(可能需要多执行几次才会报错,但并不影响本文内容),为什么呢?

这段代码大部分逻辑用的都是官方的api,所以这些地方肯定是没问题的,需要我们自己写逻辑的唯一的地方就是list.sort方法传递的参数:Comparator。

看下我们怎么写的,我们返回了 (int) (o1 - o2),看出问题了吗?

o1 - o2的结果还是long啊,如果这个值大于int范围,在我们把它转成int后,结果就溢出处理了,这时,该表达式返回的结果和我们预期的结果就不相同了。

我估计很多人都踩过这坑吧。

那正确的解决方式是什么呢?

把上面程序中的sort行注释掉,用它下面Long::compare的sort行,再试试是不是就可以了。

看下Long::compare的对应实现:

// java.lang.Long

public static int compare(long x, long y) {

return (x < y) ? -1 : ((x == y) ? 0 : 1);

}

这才是long的compare的标准方式!

还是那句话,官方库带有的方法就用官方的,这能让你少踩很多坑。

完。

更多原创文章,请关注我微信公众号:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值