You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遍历ArrayList时添加元素遇问题:外层循环仅执行一次求助

问题分析与解决方案

我一眼就看出问题出在ListIterator的cursor位置管理上!你的代码逻辑看起来没问题,但ListIterator的add()方法的行为和你预想的不一样,直接导致了外层循环只执行一次。

问题根源拆解

我们一步步走一遍你的代码执行流程:

  1. 初始时dirs只有一个根目录,ListIterator的cursor(迭代器的当前位置)停在索引0处。
  2. 第一次外层循环:iterator.hasNext()返回true,调用iterator.next()取出根目录,此时cursor会移动到索引1的位置(根目录的下一位)。
  3. 遍历根目录的子文件时,每调用一次iterator.add(file),新目录会被插入到当前cursor的位置,然后cursor自动移动到新元素的后面。比如你添加了3个子目录,最后cursor会停在索引1+3=4的位置,而此时dirs的总大小是1+3=4。
  4. 外层循环准备下一次迭代时,iterator.hasNext()会检查cursor是否小于列表大小——此时cursor等于列表大小,返回false,循环直接终止,新添加的子目录根本没机会被遍历到!

修正方案:用索引遍历替代ListIterator

想要遍历动态增长的列表,用普通的索引遍历是最直观且不易出错的方式。我们可以用while循环配合索引来实现:

int i = 0;
while (i < dirs.size()) {
    File currentDir = dirs.get(i);
    i++; // 先递增索引,避免后续添加元素影响当前迭代
    
    // 避免listFiles()返回null导致空指针
    File[] files = currentDir.listFiles();
    if (files == null) {
        continue;
    }
    
    for (File file : files) {
        if (checkCondition(file)) {
            fileList.add(file);
        }
        if (file.isDirectory()) {
            dirs.add(file); // 直接添加到列表末尾
        }
    }
}

为什么这个方案能工作?

  • 我们用索引i来跟踪当前要处理的目录,每次处理完一个目录后先递增i,这样即使后续向dirs添加新元素,也不会打乱当前的迭代顺序。
  • 循环条件i < dirs.size()会动态判断:每次添加新目录后,dirs.size()会变大,i会一直走到列表的最新长度,确保所有目录(包括动态添加的)都会被处理。

额外提示

别忘了处理currentDir.listFiles()返回null的情况——当目录没有读取权限、不是目录或者不存在时,这个方法会返回null,直接遍历会抛出NullPointerException,所以加个判断很有必要。

内容的提问来源于stack exchange,提问作者Yes92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:02:55