1. Java

List按规则删除元素

0、前言

上一次看阿里的java开发手册(华山版),知道了foreach循环内不能对元素进行remove/add操作。但是当我们的确需要遍历一个list去剔除一些元素时,那么应该如何操作才够优雅呢?

1、直接使用for循环

这里先说一下规则:删除值等于2或3的元素

List<Integer> list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
    list.add(i);
}

for (int i = 0; i < list.size(); i++) {
    if (list.get(i) == 2 || list.get(i) ==  3){
        list.remove(i);
    }
}
list.forEach(System.out::println);

​ 下面是运行结果

0
1
3
4
5
6
7
8
9

很明显3应该被删除,但是没有被删!这是因为我们在每次remove元素时,该被移除的元素后的所有元素的index都会向前移动一位!

1.1、改进版fori

List<Integer> list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
    list.add(i);
}

for (int i = list.size() - 1; i >= 0; i--) {
    if (list.get(i) == 2 || list.get(i) ==  3){
        list.remove(i);
    }java
}
list.forEach(System.out::println);

倒着fori的话,如果每次只移除一个元素还是可以的。

2、使用迭代器

List<Integer> list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
    list.add(i);
}

// 使用迭代器
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
    Integer next = iterator.next();
    if (next == 2 || next == 3){
        iterator.remove();
    }
}
list.forEach(System.out::println);

下面是运行结果

0
1
4
5
6
7
8
9

这下就正常了。

3、优雅的写法

该写法由IDEA提示得出,当我写了2中的while代码时,IDEA提示我The loop could be replaced with Collection.removeIf ,点击替换后得到如下结果

List<Integer> list = new LinkedList<>();
for (int i = 0; i < 10; i++) {
    list.add(i);
}

list.removeIf(next -> next == 2 || next == 3);
list.forEach(System.out::println);

这个removeIf方法点击去看一下,这是注释

Removes all of the elements of this collection that satisfy the given predicate. Errors or runtime exceptions thrown during iteration or by the predicate are relayed to the caller.
Params:
filter – a predicate which returns true for elements to be removed
Returns:
true if any elements were removed
Throws:
NullPointerException – if the specified filter is null
UnsupportedOperationException – if elements cannot be removed from this collection. Implementations may throw this exception if a matching element cannot be removed or if, in general, removal is not supported.
Implementation Requirements:
The default implementation traverses all elements of the collection using its iterator. Each matching element is removed using Iterator.remove(). If the collection's iterator does not support removal then an UnsupportedOperationException will be thrown on the first matching element.
Since:
1.8

闭包还是666.