前言
最近有些纠结,我从数据库查出来的list结果,究竟是空的,还是有数值的,假如我进行了遍历操作,会报空指针异常吗?今天我就来研究一下。
1. list = null 时
List<RedisDoubleAccConModel> conDoubleList = null;
1.1 使用下标遍历
for(int i = 0; i < conDoubleList.size(); i++){
System.out.println(conDoubleList.get(i));
}
查看源码可知,size()未被static修饰,list对象为null,如何调用list里面非静态方法?
1.2 迭代遍历、forEach
Iterator iter = conDoubleList.iterator();
while (iter.hasNext()) {
System.out.println(iter);
}
for(RedisDoubleAccConModel model : conDoubleList){
System.out.println(model);
}
1.3 stream().forEach
conDoubleList.stream().forEach(con->{
System.out.println(conDoubleList);
});
1.4 小结
下图中,通过对比源码和反编译后的代码,我们可以得出结论,本文所涉及的遍历方式中,除了下标遍历,其余全部都是迭代遍历的延伸。 无论是哪种遍历方式,只要list=null,都是报空指针异常(道理同1.1所讲)。
2. list = new ArrayList() 时
public static void main(String[] args) {
List<RedisDoubleAccConModel> conDoubleList = new ArrayList();
for(int i = 0; i < conDoubleList.size(); i++){
System.out.println(conDoubleList.get(i));
}
Iterator iter = conDoubleList.iterator();
while (iter.hasNext()) {
System.out.println(iter);
}
for(RedisDoubleAccConModel model : conDoubleList){
System.out.println(model);
}
conDoubleList.stream().forEach(con->{
System.out.println(conDoubleList);
});
}
查看运行可以可知, list = new ArrayList() 时,本文中所涉及的遍历方式,全部可按照预期设想,正常运行。
3. 扩展:去除list中满足特定条件的数据
public static void main(String[] args) {
List<RedisDoubleAccConModel> conDoubleList = new ArrayList();
conDoubleList.add((new RedisDoubleAccConModel()));
System.out.println(conDoubleList);
conDoubleList.removeIf(item ->
CollectionUtils.isEmpty(item.getThreshold()) && StringUtils.isEmpty(item.getId())
);
System.out.println(conDoubleList);
}
代码逻辑就是去掉集合里面,threshold 和 id 为空的数据,**->**右边的运算结果为boolean即可。运行结果如下:
迭代遍历可以用来去除集合中的元素,为何下标遍历就不行呢?
逻辑分析如下,如有误,欢迎指正。
集合,过滤掉 B,C,E三个数据
[ A, B, C, D, E] 初始size = 5
size 5 5 4 3
i 0 1 2 3
i<size? Y Y Y N -- 结束循环
去掉该元素? N Y Y
预测list集合中,剩余元素为 [ A, D, E]