你已经了解到了,通过Java8在Collection接口中新添加的stream方法,可以将任何集合转化为一个Stream。如果你面对的是一个数组,也可以用静态的Stream.of方法将它转化为一个Stream:
package java8test; import java.util.stream.Stream; public class T6 { public static void main(String[] args) { //使用Stream的静态方法of Stream<String> words = Stream.of("ab,cd,ef,gh".split(",")); System.out.printf("num: %d", words.count()); } }
of方法接受可变长度的参数,因此你可以构造一个含有任意个参数的Stream:
package java8test; import java.util.stream.Stream; public class T6 { public static void main(String[] args) { //使用Stream的静态方法of,参数为任意数量的参数 Stream<String> words = Stream.of("gently","down","the","stream"); System.out.printf("num: %d", words.count()); } }
使用Arrays.stream(array,from,to)方法将数组的一部分转化为Stream。示例:
package java8test; import java.util.Arrays; import java.util.stream.Stream; public class T6 { public static void main(String[] args) { String[] arr = {"11","22","33","44","55"}; //注意这里 Stream<String> words = Arrays.stream(arr,1,3); System.out.printf("first:%s", words.findFirst().get()); } }
要创建一个不含任何元素的Stream,可以使用静态的Stream.empty方法:
package java8test; import java.util.stream.Stream; public class T6 { public static void main(String[] args) { //示例 //泛型<String>会被编译器推导出来,这同Stream.<String>empty()一样 Stream<String> silence = Stream.empty(); System.out.println(silence.count()); } }
Stream接口有两个用来创建无限Stream的静态方法。generate方法接受一个无参数的函数(或者,从技术上来说,是一个Supplier<T>接口的对象)。当你需要一个Stream值时,就可以调用该方法来产生一个值。你可以通过如下代码来创建一个含有常量值的Stream:
package java8test; import java.util.stream.Stream; public class T6 { public static void main(String[] args) { //示例,使用generate()方法产生一个值 Stream<String> echos = Stream.generate(() -> "Echo"); System.out.println(echos.findFirst().get()); } }
或者一个含有随机数字的Stream:
package java8test; import java.util.stream.Stream; public class T6 { public static void main(String[] args) { //示例,使用generate()方法产生一个随机数 Stream<Double> echos = Stream.generate(Math::random); System.out.println(echos.findFirst().get()); } }
要创建一个形如0 1 2 3 4 ....的无限序列,你可以使用iterate方法。它接受一个“种子(seed)”值和一个函数(从技术上讲,是一个UnaryOperator<T>接口的对象)作为参数,并且会对之前的值重复应用该函数。例如:
//示例,使用iterator方法产生一个无限序列 Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE));
序列中的第一个元素是种子BigInteger.ZERO;第二个值是f(seed),或者1;下一个元素是f(f(seed)),或者2,以此类推。
注意:在java8中,添加了许多能够产生Stream的方法。例如,Pattern类添加了一个splitAsStream的方法,能够按照正则表达式对CharSequence对象进行分隔。你可以使用如下代码对一个字符串按照单词进行分隔。
静态方法Files.lines会返回一个包含文件中所有行的Stream。Stream接口有一个父接口AutoCloseable。当在某个Stream上调用close方法时,底层的文件也会被关闭。为了确保关闭文件,最好使用java7中提供的try-with-resources语句,如下:
try(Stream<String> lines = Files.lines(path)){ //对lines进行一些处理 }
这样,当正常退出try语句块或者抛出异常时,Stream与其关联的底层文件都将被关闭。