如何检查并删除List<Object>中的String类型元素
问题分析与解决方案
你的代码存在几个关键问题:
- 用增强for循环遍历列表时直接调用
remove()会触发ConcurrentModificationException,因为遍历过程中列表结构被修改,迭代器和列表状态不一致。 - 判断逻辑完全错误:
object.contains("")并非所有对象都支持(比如Integer就没有这个方法),而且就算是字符串,contains("")始终返回true,但你调用remove("")是试图移除空字符串,根本不是当前遍历到的String元素。 - 没有正确判断元素类型:应该用
instanceof来检查元素是否为String类型。
正确解法1:使用迭代器(最安全的遍历删除方式)
迭代器专门提供了remove()方法,能在遍历过程中安全修改列表:
public static void main(String[] args) { List<Object> listToFilter = new ArrayList<>(); listToFilter.add("String"); listToFilter.add(12); listToFilter.add(111); listToFilter.add("Poop"); listToFilter.add("Pee"); listToFilter.add(590); listToFilter.add("___"); Iterator<Object> iterator = listToFilter.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); if (obj instanceof String) { iterator.remove(); } } System.out.println(listToFilter); }
正确解法2:使用Java 8+的removeIf方法(最简洁)
如果你的项目基于Java 8及以上版本,removeIf可以一行完成需求,底层依赖迭代器实现,不会出现并发修改问题:
public static void main(String[] args) { List<Object> listToFilter = new ArrayList<>(); listToFilter.add("String"); listToFilter.add(12); listToFilter.add(111); listToFilter.add("Poop"); listToFilter.add("Pee"); listToFilter.add(590); listToFilter.add("___"); listToFilter.removeIf(obj -> obj instanceof String); System.out.println(listToFilter); }
正确解法3:倒序普通for循环
如果用普通for循环,必须倒序遍历,否则删除元素后后续元素索引移位,会导致漏删:
public static void main(String[] args) { List<Object> listToFilter = new ArrayList<>(); listToFilter.add("String"); listToFilter.add(12); listToFilter.add(111); listToFilter.add("Poop"); listToFilter.add("Pee"); listToFilter.add(590); listToFilter.add("___"); for (int i = listToFilter.size() - 1; i >= 0; i--) { Object obj = listToFilter.get(i); if (obj instanceof String) { listToFilter.remove(i); } } System.out.println(listToFilter); }
以上三种方法运行后都会输出[12, 111, 590],成功移除所有String类型元素。
内容的提问来源于stack exchange,提问作者Chernosmaga
相关产品推荐
相关产品推荐

