今天写课程设计的代码,在程序中有一部分代码涉及到遍历整个数组,并且检查数组中的每一个元素是否符合要求,对于不符号要求的数组元素删除之,刚开始的时候,就像平常写遍历数组的方式遍历,并且检查数组中的元素,对于不符合的删除它,代码片段如下:
for (int i = 0; i < borrowList.size(); i++) {
if(!( borrowList.get(i).getBroRecord().getEndDate().after(currntDate) && borrowList.get(i).getBroRecord().getTimeCount() > 0) )
{
borrowList.remove(i);
}
}
但是,通过测试发现,这种方式并不能够达到预期的结果,通过简单的思考发现,这种问题曾经遇到过,产生这种逻辑错误的原因是当每一次删除一个元素的时候,整个数组发生了变化,数组长度发生了变化,但是此时i并没有重新回到0,导致不能够从头开始遍历数组,从而,导致错过了数组中元素i之前的元素的遍历。经过上述思考之后,我代码改成如下的样子:
for (int i = 0; i < borrowList.size(); i++) {
if(!( borrowList.get(i).getBroRecord().getEndDate().after(currntDate) && borrowList.get(i).getBroRecord().getTimeCount() > 0) )
{
borrowList.remove(i);
i = -1;
}
}
然后就达到了预期的结果。
总结:
通过这个逻辑上的错误,得到一条经验:当需要遍历一个容器时并且需要删除其中某个元素的时候,在每次删除一个元素之后都需要在从头开始遍历这个容器(就是将容器的遍历标记变成刚开始的值)。
下面介绍一下for循环语句的执行过程:
for循环的执行顺序用如下表达式:
for(expression1;expression2;expression3)
{
expression4;
}
执行的顺序应该是:
1)第一次循环,即初始化循环。
首先执行表达式expression1(一般为初始化语句);再执行expression2(一般为条件判断语句),判断expression1是否符合expression2的条件;如果符合,则执行expression4,否则,停止执行;最后执行expression3。
2)第N(N>=2)次循环
首先执行expression2,判断在expression3是否符合在expression2要求;如果符合,则继续执行在expression4,否则,停止执行。最后执行在expression3。如此往复,直至expression3不满足在expression2条件是为止。
总结:
总的来说,执行的顺序是一致的。先条件判断(expression2),再函数体执行(expression4),最后for执行(expression3)。往复......区别在于,条件判断的对象。第一次判断时,对象为初始化语句(expression1),后续的判断对象为执行后的结果(expression3)。