Java Stream 中 filter 方法源码解析

2023-12-29 17:51:28

Java Stream 中 filter 方法源码解析

在Java的Stream API中,filter方法是用于过滤流中元素的关键操作之一。本文将深入解析filter方法的源码,理解其内部实现和机制。

Stream 接口中的 filter 方法

首先,让我们看一下Stream接口中filter方法的声明:

Stream<T> filter(Predicate<? super T> predicate);

这个方法接受一个Predicate参数,用于定义过滤条件。Predicate是一个函数式接口,其test方法返回boolean值。

filter 方法的实现

filter方法的实现实际上是在BaseStream接口中定义的。以下是BaseStream接口中关于filter方法的默认实现:

default Stream<T> filter(Predicate<? super T> predicate) {
    Objects.requireNonNull(predicate);
    return (Stream<T>) (isParallel()
            ? new ReferencePipeline.Head<>(this, StreamOpFlag.NOT_SIZED, null, OpFilter.makeRef(predicate), Shape.UNKNOWN_SIZE)
            : new ReferencePipeline.Head<>(this, StreamOpFlag.NOT_SIZED, null, OpFilter.makeRef(predicate)));
}

解析这段代码:

  • Objects.requireNonNull(predicate);:确保传入的predicate不为null,否则抛出NullPointerException
  • isParallel():检查流是否为并行流。
  • new ReferencePipeline.Head<>:创建一个新的ReferencePipeline.Head对象,表示流的头部操作。如果流是并行的,会传入额外的参数 StreamOpFlag.NOT_SIZEDShape.UNKNOWN_SIZE
  • OpFilter.makeRef(predicate):创建一个表示过滤操作的OpFilter对象,并将predicate传递给它。

OpFilter 类

OpFilter类是Stream操作的内部实现之一,用于表示过滤操作。以下是关键部分的源码:

final class OpFilter<T> implements ReferencePipeline.StatefulOp<T, T>, OpFilterFactory<T, T> {
    // ...

    static <T> StreamShape<T> toStreamShape(boolean notKnown) {
        return notKnown ? StreamShape.REFERENCE : StreamShape.SIZED;
    }

    @Override
    public <S> Node<T> opEvaluateParallel(PipelineHelper<T> helper, Spliterator<S> spliterator, IntFunction<T[]> generator) {
        return Nodes.filter(helper, spliterator, true, generator);
    }

    // ...
}

这段代码展示了OpFilter类的一部分实现。它包含一个opEvaluateParallel方法,用于在并行流中进行过滤操作。在这里,它调用了Nodes.filter方法,这个方法会根据给定的Spliterator在并行环境中执行过滤操作。

示例用法

List<String> stringList = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");

Stream<String> filteredStream = stringList.stream()
        .filter(s -> s.length() > 5);

filteredStream.forEach(System.out::println);

在这个例子中,我们使用filter方法过滤了长度大于5的字符串。在实际执行中,filter方法会根据传入的Predicate对流进行过滤,并返回一个新的流。在内部,它会创建一个新的OpFilter操作来表示这个过滤操作。

文章来源:https://blog.csdn.net/cxkjntm123/article/details/135241840
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。