ArrayList遍历时移除元素

前言

今天开发中,发现服务器返回的json数据中,对于空数组,服务器并不是返回[],而是返回[null],这也代表了数组为空,也是合法的json结构,但是使用Gson解析时,比如我解析为集合,它会解析成包含一个null元素的ArrayList,所以我需要从列表中移除掉null元素,然后再判断集合是否为空,为空就提示无数据,不为空就展示列表。

❌ 错误方式

java

java 复制代码
for (String item : list) {
    if (item == null) {
        list.remove(item); // 抛 ConcurrentModificationException
    }
}

✅ 方式一:Iterator(最传统)

java

java 复制代码
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    if (item == null) {
        iterator.remove(); // 用 iterator 自己的 remove,安全
    }
}

✅ 方式二:removeIf(最简洁,推荐)

java

java 复制代码
list.removeIf(item -> item == null);

// 更简洁
list.removeIf(Objects::isNull);

✅ 方式三:倒序 for 循环

java

java 复制代码
for (int i = list.size() - 1; i >= 0; i--) {
    if (list.get(i) == null) {
        list.remove(i);
    }
}

倒序的原因:正序删除元素后,后续元素索引会前移,容易跳过元素;倒序删除不影响前面元素的索引。


✅ 方式四:正序 for 循环(需手动处理索引)

java

java 复制代码
for (int i = 0; i < list.size(); i++) {
    if (list.get(i) == null) {
        list.remove(i);
        i--; // 删除后索引前移,需要补偿
    }
}

总结
方式 推荐度 说明
removeIf ⭐⭐⭐⭐⭐ 最简洁,Java 8+
Iterator.remove() ⭐⭐⭐⭐ 通用,兼容性好
倒序 for 循环 ⭐⭐⭐ 直观,不易出错
正序 for 循环 ⭐⭐ 需要手动 i--,容易忘
for-each 直接remove 抛异常

日常开发首选 removeIf,需要兼容低版本用 Iterator

如果使用kotlin还可以用list.filterNotNull(),但它不是直接改原集合,而是返回新集合。