26.列表遍历删除使用实例

一灰灰blogJava编程技巧JDK编程技巧约 604 字大约 2 分钟

实战26:列表遍历删除使用实例

在实际的业务开发中,容器的遍历可以说是非常非常常见的场景了,遍历删除呢,用的机会也不会少,但你真的会用么?

1. List遍历删除

对于列表,这里以ArrayList进行举例说明,下面给出几种经常会遇到的写法

首先初始化一个list数组

List<String> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
    list.add(i + ">index");
}

1.1. foreach

这个属于我们最常见的foreach循环,在循环内部判断满足条件的直接删除

for (String id : list) {
    if (id.contains("2")) {
        list.remove(id);
    }
}

上面这种写法导致的问题,很容易可以发现,因为上面代码跑完之后,堆栈就出来了

IMAGE
IMAGE

很典型的并发修改错误,在foreach循环中不允许删除,新增

1.2. 普通for循环

for (int index = 0; index < list.size(); index++) {
    if (index % 5 == 0) {
        list.remove(index);
    }
}
System.out.println(list);

上面这种写法呢?我们希望把列表中,第0,5,10,15位置的元素干掉,正常执行,倒是不会报错,然而输出的结果却和我们的预期不一致

[1>index, 2>index, 3>index, 4>index, 5>index, 7>index, 8>index, 9>index, 10>index, 11>index, 13>index, 14>index, 15>index, 16>index, 17>index, 19>index]

for循环中,另外一种写法可能更加常见,为了避免每次都访问 list.size() 方法,我可能提前用一个变量保存数组大小

int size = list.size();
for (int index = 0; index < size; index++) {
    if (index % 5 == 0) {
        list.remove(index);
    } else {
        System.out.print(list.get(index));
    }
}

上面这个问题就很明显了,数组越界

2>index3>index4>index5>index8>index9>index10>index11>index14>index15>index16>index17>indexException in thread "main" java.lang.IndexOutOfBoundsException: Index: 16, Size: 16
  at java.util.ArrayList.rangeCheck(ArrayList.java:659)
  at java.util.ArrayList.get(ArrayList.java:435)

1.3. 迭代方式

下面这种可以说是标准的迭代删除的写法了,基本上大多都是这么玩


Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String tmp = iterator.next();
    if (tmp.contains("2")) {
        iterator.remove();
    }
}

1.4. jdk8+ 流方式

jdk8+ 推荐下面这种写法,简洁明了

list.removeIf(s -> s.contains("3"));

2. 小结

注意不要在for/foreach遍历过程中删除元素,如果有移除元素的需求,使用迭代器;或者使用jdk8的流式写法也行

Loading...