java.util.List的remove()方法使用技巧

本文探讨了在Java中遍历List并删除指定元素时遇到的问题。直接在for循环中使用list.remove方法会导致某些元素被跳过。文章提供了一种正确的做法:利用Iterator及其remove方法来确保所有元素都能被正确地遍历和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.list.remove(i)

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(3);
    list.add(4);
         
    for (int i=0; i<list.size(); i++) {
        if (list.get(i) == 3) {
            list.remove(i);//这样写不对,需要写成list.remove(i--) 
        }
    }
         
    System.out.println(list);
}

如果要遍历list进行过滤,比如过滤掉值为3的对象。本以为这代码再简单不过,可还是掉坑里了,上面的代码这样写的话,元素3是过滤不完的。只要list中有相邻2个相同的就过滤不完List调用remove(index)方法后,会移除index位置上的元素,index之后的元素就全部依次左移,即索引依次-1要保证能操作所有的数据,需要把index-1,否则原来索引为index+1的元素就无法遍历到(因为原来索引为index+1的数据,在执行移除操作后,索引变成index了,如果没有index-1的操作,就不会遍历到该元素,而是遍历该元素的下一个元素)。

同样,Map通过keySet()或entrySet()遍历时,不能删除里面的元素,否则会报java.util.ConcurrentModificationException

为了避免出现以上情况,需要对List或Map进行遍历且要进行删除操作时一定要使用迭代器Iterator,通过iterator.remove()来删除。

二.建议使用iterator.remove方法

if (null != list && list.size() > 0) {
    Iterator it = list.iterator();  
    while(it.hasNext()){
        Student stu = (Student)it.next(); 
        if (stu.getStudentId() == studentId) {
            it.remove(); //移除该对象
        }
    }
}



转载于:https://my.oschina.net/xsh1208/blog/504526

### Java 中 `java.util.AbstractList` 的 `remove` 方法为何会抛出 `UnsupportedOperationException` 在 Java 集合框架中,`AbstractList` 是一个抽象类,它实现了部分 `List` 接口的功能。对于某些方法(如 `remove` 和 `add`),如果子类未对其进行覆盖,则它们会在默认实现中抛出 `UnsupportedOperationException`[^1]。 #### 原因分析 `AbstractList` 提供了一个基础结构用于创建列表类型的集合。然而,默认情况下,它的许多修改操作(如 `remove`、`add` 等)并未实际实现具体功能,而是被设计为抛出异常。这种设计的主要目的是为了支持不可变或只读的列表实现。例如: - 当使用 `Arrays.asList()` 创建列表时,返回的是一个内部类 `java.util.Arrays.ArrayList`,它是 `AbstractList` 的子类[^2]。 - 此类并没有重写 `remove` 或其他修改方法,因此当尝试调用这些方法时,就会触发 `UnsupportedOperationException`。 以下是相关代码片段展示这一行为的原因: ```java public E remove(int index) { throw new UnsupportedOperationException(); } ``` 上述代码来自 `AbstractList` 类中的默认实现,表明如果没有显式定义如何执行删除操作,则直接抛出异常。 #### 解决方案 为了避免此类问题的发生,可以将由 `Arrays.asList()` 返回的结果进一步封装至可变的 `ArrayList` 实例中。这样做的好处在于新对象能够完全支持所有的增删改查操作。下面是一个简单的例子演示此过程: ```java // 初始数组 Integer[] array = {1, 2, 3}; // 使用 Arrays.asList() 得到固定大小的列表 List<Integer> fixedSizeList = Arrays.asList(array); // 尝试移除元素将会失败并引发异常 try { fixedSizeList.remove(0); } catch (Exception e) { System.out.println(e.getMessage()); // 输出 Unsupported operation exception. } // 转换为真正的 ArrayList 来允许动态调整 List<Integer> arrayList = new ArrayList<>(fixedSizeList); // 成功移除第一个元素 arrayList.remove(0); System.out.println(arrayList); // 结果应显示剩余两个数值 [2, 3] ``` 通过以上方式处理后的数据集即可正常使用各种变更型 API 功能而不会遇到之前提到过的限制情况了。 ### 总结 由于 `AbstractList` 及其派生类可能并不总是提供完整的 CRUD 支持,在开发过程中需特别留意所使用的具体类型及其特性。若需要具备全面的操作能力则建议尽早转型成像标准版 `ArrayList` 这样的容器形式加以管理维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值