创建流的方法有很多,本文将介绍如何从值序列、数组、文件来创建流,甚至由生成函数来创建流。

1.由值来创建流

可以使用静态方法Stream.of,通过显式值来创建流。它可以接受任意数量的参数。例如,以下代码直接使用Stream.of创建了一个字符串流。然后可以将字符串转换为大写,再一个个打印出来:

Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action"); 
stream.map(String::toUpperCase).forEach(System.out::println);

可以使用empty得到一个空流,

Stream<String> emptyStream = Stream.empty();

2.由数组创建流

可以使用Arrays.stream从数组创建一个流。它接受一个数组作为参数。例如,可以将一个原始类型int的数组转换成一个IntStream,

例如:

int[] numbers = {2, 3, 5, 7, 11, 13}; 
int sum = Arrays.stream(numbers).sum();

3.由文件生成流

Java中用于处理文件等i/o操作的NIO API(非阻塞I/O)已更新,已便利用Stream API。java.nio.file.Files中的很多静态方法都会返回一个流。例如,一个很有用的方法是Files.lines,它会返回一个由指定文件中的各行构成的字符流。可以用这个方法看看一个文件中由多少各不相同的词:

java stream 参数final java stream.of_数组

你可以使用Files.lines得到一个流,其中的每一个元素都是给定文件中的一行。然后使用Lambda表达式拆分成单词。注意flatMap产生一个扁平的单词流,而不是给每一行生成一个单词流。最后调用distinct()和count()方法链接起来。

4.由函数生成流:创建无限流

Stream API 提供了两个静态方法来从函数生成流:Stream.iterate和Stream.generate。这两个操作可以创建所谓的无限流:不像从固定集合创建的流那样由固定大小的流。由iterate和generate产生的流会用给定的函数按需创建值。因此可以无穷的计算下去。
(1)迭代

Stream.iterate(0, n -> n + 2) 
 .limit(10) 
 .forEach(System.out::println);

 

iterate方法接受一个初始值(在这里是0),还有一个Lambda表达式(UnaryOperator<t>类型)。此操作如果没有limit()方法进行截断,将不断的打印偶数,是一个无限流。

(2)生成

与iterate方法类似,generate方法也可以按需生成无限流,但generate不是依次对每一个新生成的值应用函数的。它接受一个Supplier<T>类型的Lambda提供的新值。

Stream.generate(Math::random) 
 .limit(5) 
 .forEach(System.out::println);

输出:

0.9410810294106129 
0.6586270755634592 
0.9592859117266873 
0.13743396659487006 
0.3942776037651241