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

为何第二个for循环无法完整打印ArrayList?

问题分析与解决方案:ArrayList遍历删除时的元素遗漏问题

你遇到的情况很典型——第一个for循环能完整打印所有元素,但第二个循环里的'2'就是没出现在控制台,而且你本来想实现保留第一个元素(无论是否为字符)+ 其余非字符元素的目标,结果却出了问题。

核心问题原因

问题出在遍历ArrayList时同时执行remove操作,导致索引混乱,咱们一步步拆解你的代码逻辑:

  1. 初始ArrayList有两个元素:'a'(索引0)、'2'(索引1)
  2. 第二个循环启动,i=0:
    • 打印'a',判断它是字母(ASCII在65-122区间),执行al.remove(0)
    • 此时ArrayList只剩'2',它的索引自动变成了0
  3. 循环继续,i自增到1,而此时al.size()已经变成1,i < al.size()(1 < 1)不成立,循环直接结束
    • 所以'2'根本没机会进入循环被打印,自然就看不到输出了

两种可行解决方案

方案一:倒序遍历(最直接的修复方式)

倒着遍历的话,删除前面的元素不会影响后面未遍历元素的索引,完美避开索引混乱问题。同时我们可以直接从索引1开始遍历,确保第一个元素不被处理:

import java.util.ArrayList;
public class Test1 {
    public static void main(String[] args) {
        ArrayList<Character> al = new ArrayList<>();
        al.add('a');
        al.add('2');
        
        // 第一个循环正常打印所有元素
        for(int i=0;i<al.size();i++){
            System.out.println("element entered in for loop: "+al.get(i));
        }
        
        // 倒序遍历,从索引1开始(保留第一个元素)
        for(int i = al.size() - 1; i >= 1; i--){
            System.out.println("element entered for check: "+al.get(i));
            char c = al.get(i);
            // 直接用字符常量判断范围,比ASCII数字更直观
            if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')){
                al.remove(i);
            }
        }
        
        // 打印处理后的结果验证
        System.out.println("处理后的ArrayList元素:");
        for(Character obj : al){
            System.out.println(obj);
        }
    }
}

方案二:使用Iterator(Java官方推荐的遍历删除方式)

Java中遍历集合并删除元素,最安全的方式是用Iterator,它会自动同步集合状态,完全避免索引问题:

import java.util.ArrayList;
import java.util.Iterator;
public class Test1 {
    public static void main(String[] args) {
        ArrayList<Character> al = new ArrayList<>();
        al.add('a');
        al.add('2');
        
        // 第一个循环正常打印所有元素
        for(int i=0;i<al.size();i++){
            System.out.println("element entered in for loop: "+al.get(i));
        }
        
        // 使用Iterator处理,保留第一个元素
        Iterator<Character> iterator = al.iterator();
        // 先取出第一个元素,直接保留
        if(iterator.hasNext()){
            System.out.println("保留第一个元素:"+iterator.next());
        }
        // 遍历剩余元素
        while(iterator.hasNext()){
            char c = iterator.next();
            System.out.println("element entered for check: "+c);
            if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')){
                iterator.remove(); // 用Iterator的remove方法,不会有索引混乱
            }
        }
        
        // 打印处理后的结果验证
        System.out.println("处理后的ArrayList元素:");
        for(Character obj : al){
            System.out.println(obj);
        }
    }
}

额外优化建议

  • 把代码里的&换成&&:&&是短路与,效率更高,逻辑也更符合常规需求
  • 给ArrayList指定泛型(比如ArrayList<Character>):避免强制类型转换,代码更安全可读
  • 判断字符范围时用'A'、'z'这类字符常量:比直接写ASCII数字65、122可读性强很多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:05:29