List遍历删除解决方案:遍历删除,迭代删除,removeIf

1 容易出现的问题:

 1 package collectionDemo.list;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public class ListDemo {
 7 
 8     public static void main(String[] args) {
 9         List<String> sList = new ArrayList<String>();
10         sList.add("0");
11         sList.add("1");
12         sList.add("2");
13         sList.add("3");
14         sList.add("4");
15         System.out.println(sList);
16         // 对list进行遍历,并按条件进行删除
17         for (int i = 0; i < sList.size(); i++) {
18             if (i == 1 || i == 2) {
19                 sList.remove(i);
20             }
21         }
22         System.out.println(sList);
23 
24     }
25 
26 }

输出结果为:

[0, 1, 2, 3, 4]
[0, 2, 4]

  乍一看代码,像是实现删除索引为1和2的元素。但执行结果却并非如此。在执行遍历集合删除元素时,当i==1时,集合remove掉索引为1(i)的元素,移除字符串1,此处是正常逻辑。但执行到i==2时,remove的却是字符串3。原因如下:

  使用普通for循环遍历ArrayList时,是以索引为依据进行遍历的。在遍历过程中remove元素会导致索引的混乱。比如上例中,当remove(1)后,集合size将发生变化,元素将变少,字符串2所对应的索引将由2变为1,后边的字符串3和4依次类推索引变为2和3,执行下一次循环时,i++为2,此时remove的是字符串3,所以导致了上述结果。

2 解决方案1:

 public class ListDemo {
 7 
 8     public static void main(String[] args) {
 9         List<String> sList = new ArrayList<String>();
10         sList.add("0");
11         sList.add("1");
12         sList.add("2");
13         sList.add("3");
14         sList.add("4");
15         System.out.println(sList);
16         // 对list进行遍历,并按条件进行删除
17         for (int i = 0; i < sList.size(); i++) {
18             if (i == 1 || i == 2) {
19                 sList.remove(i);
                       i--;
20             }
21         }
22         System.out.println(sList);
23 
24     }

添加了删除元素后对下标i进行i--操作,保证下标不错乱。

3 解决方案2:

使用迭代器对集合进行遍历,并进行集合中元素的删除操作,如:

public class ListDemo {

    public static void main(String[] args) {
        List<String> sList = new ArrayList<String>();
        sList.add("0");
        sList.add("1");
        sList.add("2");
        sList.add("3");
        sList.add("4");
        System.out.println(sList);
        Iterator<String> iterator=sList.iterator();
        while(iterator.hasNext()){
            String item=iterator.next();
            if(item.equals("1")){
                iterator.remove();
                //sList.remove(item);注释的用法是错误用法,迭代器中的迭代需使用迭代器进行删除操作,不能在使用集合的remove方法,此种用法会导致java.util.ConcurrentModificationException
            }
        }
        System.out.println(sList);

    }

}

以上举例以list为例,同理在map集合中存在同样的问题,举一反三。

4 解决方案3(推荐),使用removeIf:

package collectionDemo;

import java.util.ArrayList;
import java.util.List;

public class ListDmeo {

    public static void main(String[] args) {
        List<String> sList = new ArrayList<String>();
        sList.add("0");
        sList.add("1");
        sList.add("2");
        sList.add("3");
        sList.add("4");
        sList.removeIf(str-> str.equals("1"));
        System.out.println(sList);
    }
}

打印结果:

[0, 2, 3, 4]

removeIf内部也是使用的迭代器进行的删除操作,源码如下:

   default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值