⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/Butterfly_resting/article/details/100045181 「」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

filter是Java8 Stream的方法:

Stream filter(Predicate<? super T> predicate)

返回由与此给定谓词匹配的此流的元素组成的流。

removeIf是Java8 Collecttion的一个默认方法。

default boolean removeIf(Predicate<? super E> filter)

删除满足给定谓词的这个集合的所有元素。

removeIf和filter方法都能达到过滤/删除元素的作用。

从功能是实现上,removeIf是条件为true则过滤此元素,false则保留。而filter则是条件为false过滤此元素,而true则保留。

从时间上,要看场景,因为removeIf返回的是boolean,而filter是个intermediate operation,需要terminal operation最终来处理流,如果只是单单只做删除/过滤操作, removeIf会快些。

示例:

public static void main(String[] args) {
List list = new ArrayList(Arrays.asList(1,2,3,4,5));
long last = System.currentTimeMillis();
list.removeIf(a -> a.equals(2));
System.out.println(System.currentTimeMillis() - last);//37~38
}
public static void main(String[] args) {
List list = new ArrayList(Arrays.asList(1,2,3,4,5));
long last = System.currentTimeMillis();
list.stream().filter(a -> !a.equals(2)).collect(Collectors.toList());
System.out.println(System.currentTimeMillis() - last);//41~44
}

来看看源码实现:

removeIf是Collection接口的默认方法(Java8新增),底层实现是通过获得迭代器迭代每一个元素,满足条件的通过remove()方法删除,直到迭代完返回true,迭代完都没有满足条件的元素则返回false。如果是多个中间流参与,那么还是推荐使用filter方便。

default boolean removeIf(Predicate<? super E> filter) {
//判断是否为null
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
//迭代出现运行时异常或者错误由由Predicate被转发给调用者
if (filter.test(each.next())) {
//remove底层调用的是System.arraycopy方法,是个C++编写的native方法,操作的是指针,所有比较快
each.remove();
removed = true;
}
}
return removed;
}

每次filter都产生一个新的StatelessOp,也就新的流,通过opWrapSink不断匹配条件,当为false时则标记此流元素可过滤

 @Override
public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
//判断是否为null
Objects.requireNonNull(predicate);
//将无状态的中间操作附加到现有流中来构造新流。StreamOpFlag.NOT_SIZED表示要清除的位值
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}

@Override
public void accept(P_OUT u) {
if (predicate.test(u))
downstream.accept(u);
}
};
}
};
}
//要清除的位值
static final int NOT_SIZED = SIZED.clear;

SIZED(3,
set(Type.SPLITERATOR).set(Type.STREAM).clear(Type.OP)),

文章目录