多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Java 8 流教程 > 原文: [https://beginnersbook.com/2017/10/java-8-stream-tutorial/](https://beginnersbook.com/2017/10/java-8-stream-tutorial/) 在上一个教程中,我们学习了 java 8 中的[接口更改。在本指南中,我们将讨论**流 API**,这是 **java 8** 的另一个新功能。该 API 的所有类和接口都在`java.util.stream`包中。通过使用流,我们可以对从集合,数组,输入/输出操作返回的数据执行各种聚合操作。在我们看到如何在 Java 中使用流 API 之前,让我们看一个例子来理解流的使用。](https://beginnersbook.com/2017/10/java-8-interface-changes-default-method-and-static-method/) ## Java 流示例 要了解流的工作原理,让我们在不使用流的情况下进行示例,然后我们将看到与流相同的示例。 **在不使用流**的情况下查找某些字符串 ```java import java.util.ArrayList; import java.util.List; public class Example{ public static void main(String[] args) { List<String> names = new ArrayList<String>(); names.add("Ajeet"); names.add("Negan"); names.add("Aditya"); names.add("Steve"); int count = 0; for (String str : names) { if (str.length() < 6) count++; } System.out.println("There are "+count+" strings with length less than 6"); } } ``` 输出: ```java There are 3 strings with length less than 6 ``` **使用流**的相同示例 ```java import java.util.ArrayList; import java.util.List; public class Example{ public static void main(String[] args) { List<String> names = new ArrayList<String>(); names.add("Ajeet"); names.add("Negan"); names.add("Aditya"); names.add("Steve"); //Using Stream and Lambda expression long count = names.stream().filter(str->str.length()<6).count(); System.out.println("There are "+count+" strings with length less than 6"); } } ``` 输出: ```java 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:迭代并显示选定的整数 ```java import java.util.stream.*; public class Example { public static void main(String[] args){ Stream.iterate(1, count->count+1) .filter(number->number%3==0) .limit(6) .forEach(System.out::println); } } ``` 输出: ```java 3 6 9 12 15 18 ``` ## Java 流示例 2:连接两个流 ```java import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class Example { public static void main(String[] args) { //list 1 List<String> alphabets = Arrays.asList("A","B","C"); //list 2 List<String> names = Arrays.asList("Sansa","Jon","Arya"); //creating two streams from the two lists and concatenating them into one Stream<String> opstream = Stream.concat(alphabets.stream(), names.stream()); //displaying the elements of the concatenated stream opstream.forEach(str->System.out.print(str+" ")); } } ``` 输出: ```java A B C Sansa Jon Arya ``` #### 相关文章: 1. [Java 流`allMatch()`示例](https://beginnersbook.com/2017/11/java-8-stream-allmatch-example/) 2. [Java 流`noneMatch()`示例](https://beginnersbook.com/2017/11/java-8-stream-nonematch-example/) 3. [Java 流`anyMatch()`示例](https://beginnersbook.com/2017/11/java-8-stream-anymatch-example/)