Java 8 引入的 Stream 流是一种用于处理集合数据的高级抽象。它提供了一种函数式编程的方式来操作数据,使得代码更简洁、可读性更高,并且可以并行处理数据。
下面是 Java Stream 流的总结:
创建流:
- 从集合创建流:
stream()
?或?parallelStream()
?方法可以从集合中创建串行或并行流。- 从数组创建流:
Arrays.stream(array)
?可以从数组中创建流。- 使用 Stream.of() 创建流:
Stream.of(value1, value2, ...)
?可以直接创建流。中间操作:
- filter:根据指定条件过滤元素。
- map:对流中的每个元素应用一个函数。
- flatMap:将多个流合并成一个流。
- distinct:去重,去除流中重复的元素。
- sorted:对流中的元素排序。
- limit:限制流中元素的数量。
- skip:跳过流中的前几个元素。
- ...
终端操作:
- forEach:对流中的每个元素执行指定操作。
- toArray:将流转换为数组。
- reduce:对流中的元素进行归约操作。
- collect:将流中的元素收集到集合中。
- min、max:找出流中的最小值或最大值。
- count:返回流中的元素数量。
- anyMatch、allMatch、noneMatch:判断流中是否存在满足指定条件的元素。
- findFirst、findAny:返回流中的第一个元素或任意元素。
- ...
- Stream流的每一次中间操作都会返回一个新的Stream对象,而不会改变原来的Stream对象。这意味着每次执行中间操作时,都会创建一个新的Stream对象,而不是在原来的Stream对象上进行修改。
- 线程安全问题。
- 串行流是线程安全的,默认是单线程。
- 并行流是多线程执行的,非线程安全。
并行流:
- 使用?
parallelStream()
?方法可以将流转换为并行流,充分利用多核处理器的优势。流的延迟执行:
- Stream 操作一般是延迟执行的,只有在终端操作调用时才会真正执行。
- 在对流进行多次操作时,在没有调用终端操作之前,所有中间操作不会立即执行。(如果你不调用终端操作那中间操作就不会被执行,因为你不使用这些操作后的数据,所以就连中间操作都不执行了)
流的使用注意事项:
- 流只能被消费一次,一旦对流进行终端操作后,就无法再对同一流进行操作。
- 流操作可能会改变原始集合的状态,因此需要注意不要对同一集合进行多个流操作。
Stream 是 Java 8 引入的一个强大的工具,它提供了丰富的操作方法,可以大大简化集合数据的处理。通过灵活地使用中间操作和终端操作,我们可以实现各种复杂的数据处理需求。
在 Stream 流中对集合进行过滤操作,并不会改变原始集合的内容。Stream 操作是基于流的元素创建一个新的流,而不会对原始数据源进行修改。
例如,考虑以下示例代码:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> filteredNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); System.out.println(numbers); // [1, 2, 3, 4, 5] System.out.println(filteredNumbers); // [2, 4]
在上面的代码中,我们通过
filter
操作筛选出了偶数,但是原始的numbers
集合并没有改变。相反,我们使用collect
方法将筛选后的结果收集到了一个新的集合filteredNumbers
中。这种非破坏性的操作是 Stream API 的特征之一。它允许我们在不修改原始数据源的情况下对数据进行各种转换和处理操作。
?