纳尼?Collections对时间戳排序出错了??

记录一次排序犯的bug,说到底还是考虑不全……

问题现象

今天突然发现项目中的一个列表排序出现了错乱,顿时很慌张,原来测试过的啊,没问题的呀,这是怎么回事,赶紧定位问题,现象如下:
1-9条数据排序正常,10条以后数据排序也对。但是这两块顺序不对。正常应该先展示10条以后的数据,最后再展示1-9条数据。(后来得知,这个现象属于偶然~~和数据有关系)

列表中部分有序,但是整体排序不对……

分析

恩?这是怎么回事?
列表采用的分页加载,莫非是 分页请求 数据的原因?

¥@#&……*……@¥

一顿分析后,得出结论,分页请求没问题,不是这个原因。

列表用的是RecycleView,莫非是 常见的 列表复用 的原因?

¥@#&……*……@¥

一顿分析后,得出结论,不是没问题。

那会不会是排序本身的问题呢?

那看一下排序的代码

// 网络请求获取数据,封装再beanList中
...
// 对beanList进行排序
Collections.sort(beanList, new Comparator<Bean>() {
    @Override
    public int compare(Bean bean1, Bean bean2) {
        //        降序写法
        return (int) (bean2.getBuyTime() - bean1.getBuyTime());
    }
});
...

其实大佬一眼就能看出来原因了,奈何我这心大,看了好几遍,还总觉得没问题。
就这么几行代码咋能出错呢?还纠结了半天,最后才聚焦到了 int类型 上面……
是不是这个数值超过了int的最大值,所以计算错误了呢?

int的取值范围为: -2^31——2^31-1,即
-21 4748 3648——21 4748 3647

2147483647毫秒 ---> 2147483 秒 ---> 35791 分钟 ---> 596 小时 
≈ 25天
2147483647秒 ---> 35791406 分钟 ---> 596523小时
≈ 24855天 ≈ 68年

也就是说,如果是毫秒作为单位的话,int类型最多表示25天时间。
如果时间超过这个范围,那么就会数据错误!

如果是秒作为单位的话,int类型大约可以表示68年时间。
我这里之所以出错,是因为时间超过了这个范围,所以导致排序的时候,错误地判断了大小关系。

解决问题

至此,定位原因。解决方法也就简单了:
(尴尬,犯了基础的错误……)

Collections.sort(beanList, new Comparator<Bean>() {
    @Override
    public int compare(Bean bean1, Bean bean2) {
        //        降序写法
		// 原先采用的多次比较的方法,先判断是否是同年月,再return时间差,费时费力。
		// 感谢评论区大佬 【常威追打来福】 指点,比较方法已经修改如下:
		if(bean2.getBuyTime() - bean1.getBuyTime() > 0){
			return 1;
		}else if(bean2.getBuyTime() - bean1.getBuyTime() < 0){
			return -1;
		}else {
			return 0;
		}
    }
});

总结

程序开发是个细致的活,一定要细心呀!不要因为马虎,在基础的知识上面翻了车。
在此,再次回顾下基础类型的基础知识,切记勿再犯相关错误!

扩展

在JAVA中一共有八种基本数据类型,他们分别是
byte、short、int、long、float、double、char、boolean

byte的取值范围为-128~127,占用1个字节(-2的7次方到2的7次方-1)
short的取值范围为-32768~32767,占用2个字节(-2的15次方到2的15次方-1)
int的取值范围为(-2147483648~2147483647),占用4个字节(-2的31次方到2的31次方-1)
long的取值范围为(-9223372036854774808~9223372036854774807),占用8个字节(-2的63次方到2的63次方-1)

float 3.402823e+38 ~ 1.401298e-45(e+38表示是乘以10的38次方,同样,e-45表示乘以10的负45次方)占用4个字节
double 1.797693e+308~ 4.9000000e-324 占用8个字节

float和double是表示浮点型的数据类型,他们之间的区别在于他们的精确度不同
double型比float型存储范围更大,精度更高,所以通常的浮点型的数据在不声明的情况下都是double型的,如果要表示一个数据是float型的,可以在数据后面加上“F”。
浮点型的数据是不能完全精确的,所以有的时候在计算的时候可能会在小数点最后几位出现浮动,这是正常的。

boolean型(布尔型)
这个类型只有两个值,true和false(真和非真)

char型(文本型)
用于存放字符的数据类型,占用2个字节

采用unicode编码,它的前128字节编码与ASCII兼容,字符的存储范围在\u0000~\uFFFF

发布了70 篇原创文章 · 获赞 176 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zheng_weichao/article/details/88015343