Stream流是Java 8引入的一种用于处理集合数据的函数式编程概念。它提供了一种流式处理数据的方式,可以进行过滤、映射、排序、聚合等操作。
下面是Stream流的执行流程:
-
创建流:首先,需要有一个数据源,可以是集合、数组、I/O通道等。然后,通过调用
stream()方法或parallelStream()方法来创建一个流。例如:List<String> list = Arrays.asList("a", "b", "c"); Stream<String> stream = list.stream(); -
中间操作:一旦有了流,可以对其进行中间操作。中间操作是对数据进行转换、过滤、映射等处理,但并不会立即执行。常见的中间操作包括
filter()、map()、sorted()、distinct()等。这些操作可以连接在一起,形成一个操作链。例如:Stream<String> filteredStream = stream.filter(s -> s.startsWith("a")).map(String::toUpperCase);
中间操作方法:
filter(Predicate<T> predicate):根据指定的条件过滤流中的元素。map(Function<T, R> mapper):将流中的每个元素映射为另一个元素。flatMap(Function<T, Stream<R>> mapper):将流中的每个元素映射为一个流,并将所有流连接起来。distinct():去除流中重复的元素。sorted():对流中的元素进行排序。limit(long maxSize):截取流中的前N个元素。skip(long n):跳过流中的前N个元素。
- 终端操作:最后,需要执行一个终端操作来触发流的处理。终端操作会产生一个最终的结果或副作用。常见的终端操作包括
forEach()、collect()、reduce()、count()等。例如:filteredStream.forEach(System.out::println);
终端操作方法:
forEach(Consumer<T> action):对流中的每个元素执行指定的操作。toArray():将流中的元素转换为数组。collect(Collector<T, A, R> collector):将流中的元素收集到一个集合中。reduce(BinaryOperator<T> accumulator):将流中的元素按照指定的操作进行聚合。count():计算流中的元素个数。anyMatch(Predicate<T> predicate):检查流中是否存在满足指定条件的元素。allMatch(Predicate<T> predicate):检查流中的所有元素是否都满足指定条件。noneMatch(Predicate<T> predicate):检查流中是否没有满足指定条件的元素。findFirst():返回流中的第一个元素。findAny():返回流中的任意一个元素。
在执行终端操作时,流会根据操作链依次处理每个元素。它会按需处理数据,避免不必要的计算。这种惰性求值的特性使得流在处理大量数据时能够高效地工作。
流是一次性的,一旦执行了终端操作,流将被消耗,无法再次使用。如果需要对同一数据源进行多个操作链的处理,可以通过创建新的流来实现。