开发过程中会经常遇到当时开发想不到的问题,在此开帖整理这种问题,加强记忆和后续参考整理(持续更新中)。
- list中数据校验(正序/增序)的时候使用remove方法造成数据校验出问题
- 原因是:在list执行remove方法后,list的index索引发生变化,造成后面的子item对象躲开校验进而出现问题,比如对于一个7数量的list,当i=2的时候符合条件被移出后,后面的item补位此时的item数量变为6原有的i=3对应的是7数量中的第四个item,移出后,第四个item补到了i=2的位置,此时的后续校验i=3的时候其实是原有的第五个item,就这样第四个item躲避了校验检查。
- 解决方案: 一是使用反序/降序方式进行校验检查,i逐渐减小,对应的index索引是不变化的(remove是后面item进行补位),另一种方案是新建一个list对象,将满足的放入新的list中,原有list不执行对应的remove逻辑。
- list.map等特别是普通list,map在remove的时候(特别是增强for循环)极其容易出现ConcurrentModificationException。
原因分析:list的遍历包含for循环,迭代器,增强for循环,后面的增强for循环实质也是迭代器模式实现(java最新提供的一个语法,方便处理),迭代器是java提供遍历list等表结构工具类,是维护在一个单独线程中的且加锁,迭代器维护了list的一张索引表,在索引的同时,list删除子item,并不会同步给迭代器,迭代器找不到对应的索引item就回爆出上面异常,map遍历同list,通过迭代器模式遍历也会出现这种情况。
解决方案:
- 通过迭代器的remove方法,先删除迭代器的索引,删除的同时其会同步到list表结构删除对应的item
- 使用线程安全的表结构代替对应的list,map等
- 日期比较:
- 先通过SimpleDateFormat格式化date,然后利用date的api进行时间对比
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date bt=sdf.parse(beginTime);
Date et=sdf.parse(endTime);
if (bt.before(et)){
//表示bt小于et
}else{
--反之
}
- 先通过SimpleDateFormat格式化date并获取date的string值进行string对比,即:
String lastCurrentSigninDate = getDzCurrentsigninDate();
String currentSignInDate = TimeUtils.getFormatDate("yyyy-MM-dd");
if (TextUtils.isEmpty(lastCurrentSigninDate)) {
setDzCurrentsigninDate(currentSignInDate);
} else {
if (lastCurrentSigninDate.compareTo(currentSignInDate) < 0) {
setDzLastsigninDate(lastCurrentSigninDate);
setDzCurrentsigninDate(currentSignInDate);
}
}
map遍历方法及其正确删除方法
java增强for循环实质实现
掘金:concurrenthashmap是否真正的线程安全
比较深奥:深入剖析concurrenthashmap,底部有其第二篇
网友评论