0%

ArrayList-removeIf方法总结

前言:因为这个方法是java8新增,稍复杂,所以单独讲

removeIf

根据自定义的规则去除集合中数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
public boolean removeIf(Predicate<? super E> filter) {
// 判断对象是否为空
Objects.requireNonNull(filter);

int removeCount = 0;
final BitSet removeSet = new BitSet(size);
final int expectedModCount = modCount;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
@SuppressWarnings("unchecked")
final E element = (E) elementData[i];
if (filter.test(element)) {
removeSet.set(i);
removeCount++;
}
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}

final boolean anyToRemove = removeCount > 0;
if (anyToRemove) {
final int newSize = size - removeCount;
for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
i = removeSet.nextClearBit(i);
elementData[j] = elementData[i];
}
for (int k=newSize; k < size; k++) {
elementData[k] = null; // Let gc do its work
}
this.size = newSize;
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}

return anyToRemove;
}

Predicate

查看一下Predicate接口的源码,核心是test方法,and、 negate、or、isEqual方法则是对test的增强,其作用就是方法名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@FunctionalInterface
public interface Predicate<T> {
// 根据传入的表达式返回布尔值
boolean test(T t);

// and
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}

// 相当于!
default Predicate<T> negate() {
return (t) -> !test(t);
}

// or
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}

// ==
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}

例子

根据用户信息对用户进行筛选,使用removeIf就不用写for循环了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class User {
private String username;
private Integer age;
private String sex;

// 省略get/set、构造方法
}

public class Main {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
final String MALE = "male";
final String FEMALE = "female";
list.add(new User("张三", MALE));
list.add(new User("李四", MALE));
list.add(new User("孙婉茹", FEMALE));
list.add(new User("郑洁", FEMALE));
list.add(new User("赵山川", MALE));

// 根据年龄
list.removeIf(user -> user.getAge() >= 30);

// 根据性别
// list.removeIf(user -> user.getSex() != FEMALE);

// 使用Predicate
// Predicate<User> p1 = user -> user.getAge() >= 30;
// Predicate<User> p2 = user -> user.getSex() != FEMALE;
// list.removeIf(p1.and(p2));

list.forEach(user->System.out.println(user.getUsername()));
}
}

根据年龄

image-20200102002533537

根据性别去除数据

image-20200102002542693

-------------本文结束感谢您的阅读-------------