原文: https://beginnersbook.com/2017/10/java-8-stream-tutorial/

在上一个教程中,我们学习了 java 8 中的接口更改。在本指南中,我们将讨论流 API,这是 java 8 的另一个新功能。该 API 的所有类和接口都在java.util.stream包中。通过使用流,我们可以对从集合,数组,输入/输出操作返回的数据执行各种聚合操作。在我们看到如何在 Java 中使用流 API 之前,让我们看一个例子来理解流的使用。

Java 流示例

要了解流的工作原理,让我们在不使用流的情况下进行示例,然后我们将看到与流相同的示例。

在不使用流的情况下查找某些字符串

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class Example{
  4. public static void main(String[] args) {
  5. List<String> names = new ArrayList<String>();
  6. names.add("Ajeet");
  7. names.add("Negan");
  8. names.add("Aditya");
  9. names.add("Steve");
  10. int count = 0;
  11. for (String str : names) {
  12. if (str.length() < 6)
  13. count++;
  14. }
  15. System.out.println("There are "+count+" strings with length less than 6");
  16. }
  17. }

输出:

  1. There are 3 strings with length less than 6

使用流的相同示例

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class Example{
  4. public static void main(String[] args) {
  5. List<String> names = new ArrayList<String>();
  6. names.add("Ajeet");
  7. names.add("Negan");
  8. names.add("Aditya");
  9. names.add("Steve");
  10. //Using Stream and Lambda expression
  11. long count = names.stream().filter(str->str.length()<6).count();
  12. System.out.println("There are "+count+" strings with length less than 6");
  13. }
  14. }

输出:

  1. There are 3 strings with length less than 6

这些代码有什么区别?

两个示例的输出都是相同的,但是如果考虑代码的性能,这些示例之间会有很大的不同。
在第一个例子中,我们迭代整个列表以找到长度小于 6 的字符串。此代码中没有并行性。
在第二个例子中,stream()方法返回所有名称的流,filter()方法返回另一个长度小于 6 的名称流,count()方法减少了这个流到结果。所有这些操作都是并行发生的,这意味着我们能够在流的帮助下并行化代码。 使用流并行执行操作比不使用流的顺序执行更快。

如何在 Java 中使用流

正如我们在上面的例子中看到的那样,流的工作可以分三个阶段来解释:

  1. 创建一个流

  2. 在初始流上执行中间操作,将其转换为另一个流,依此类推进一步的中间操作。在上面的例子中,filter()操作是中间操作,可以有多个中间操作。

  3. 在最终流上执行端子操作以获得结果。在上面的例子中,count()操作是终端操作。

Java 流函数

  1. 不存储元素。它只是执行聚合操作(例如我们在上面的例子中看到的filter()count())来获得所需的数据流。

  2. 我们对集合,数组或任何其他数据源执行的聚合操作不会更改源的数据,它们只返回一个新流。例如,我们上面看到的代码是使用流操作过滤长度小于 6 的字符串,但它没有更改列表的元素。

  3. 所有流操作本质上都是懒惰,这意味着它们在需要之前不会被执行。例如,如果我们想要使用流仅显示列表的前 2 个元素,则在显示列表的第二个元素之后,流操作将在第二次迭代结束时停止。

让我们看几个 Java 流的例子:

Java 流示例 1:迭代并显示选定的整数

  1. import java.util.stream.*;
  2. public class Example {
  3. public static void main(String[] args){
  4. Stream.iterate(1, count->count+1)
  5. .filter(number->number%3==0)
  6. .limit(6)
  7. .forEach(System.out::println);
  8. }
  9. }

输出:

  1. 3
  2. 6
  3. 9
  4. 12
  5. 15
  6. 18

Java 流示例 2:连接两个流

  1. import java.util.Arrays;
  2. import java.util.List;
  3. import java.util.stream.Stream;
  4. public class Example {
  5. public static void main(String[] args) {
  6. //list 1
  7. List<String> alphabets = Arrays.asList("A","B","C");
  8. //list 2
  9. List<String> names = Arrays.asList("Sansa","Jon","Arya");
  10. //creating two streams from the two lists and concatenating them into one
  11. Stream<String> opstream = Stream.concat(alphabets.stream(), names.stream());
  12. //displaying the elements of the concatenated stream
  13. opstream.forEach(str->System.out.print(str+" "));
  14. }
  15. }

输出:

  1. A B C Sansa Jon Arya

相关文章:

  1. Java 流allMatch()示例
  2. Java 流noneMatch()示例
  3. Java 流anyMatch()示例