空Stream
在创建空流时,应该使用empty()方法:
Stream<String> streamEmpty = Stream.empty();
通常情况下,在创建流时使用empty()方法来避免对没有元素的流返回null:
public Stream<String> streamOf(List<String> list) {
return list == null || list.isEmpty() ? Stream.empty() : list.stream();
}
集合Stream
可以依据任何类型的集合(Collection,List,Set)来创建流:
Collection<String> collection = Arrays.asList("a", "b", "c");
Stream<String> streamOfCollection = collection.stream();
数组Stream
数组也可以是Stream的源:
Stream<String> streamOfArray = Stream.of("a", "b", "c");
也可以依据现有数组或数组的一部分来创建流:
String[] arr = new String[]{"a", "b", "c"};
Stream<String> streamOfArrayFull = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3);
Stream.builder()
当使用builder时,应该指定所需的类型,否则build()方法将创建Stream<Object>的实例:
Stream<String> streamBuilder = Stream.<String>builder().add("a").add("b").add("c").build();
Stream.generate()
generate()方法接受Supplier<T>来生成元素。由于产生的流是无限的,开发人员应该显式指定所需的大小,否则generate()方法将一直工作,直到超出内存限制:
Stream<String> streamGenerated = Stream.generate(() -> "element").limit(10);
上面的代码会生成包含10个字符串“element”的序列。
Stream.iterate()
创建无限流的另一种方法是使用iterate()方法:
Stream<Integer> streamIterated = Stream.iterate(40, n -> n + 2).limit(20);
函数的第一个参数就是结果Stream中的第一个元素,后面每个元素都是使用给定的函数结合上一个元素计算得出的。在上面的例子中,第二个元素就是42。
基本类型Stream
Java 8提供了从三种基本类型(int,long和double)中创建流的方式。 由于Stream <T>是泛型接口,无法将基本类型用作泛型的类型参数,因此创建了三个新的特殊接口:IntStream,LongStream和DoubleStream。
使用新接口减少了不必要的自动装箱,从而提高了效率:
IntStream intStream = IntStream.range(1, 3);
LongStream longStream = LongStream.rangeClosed(1, 3);
range(int startInclusive, int endExclusive) 方法会创建一个从第一个参数到第二个参数的有序流,该方法以步长为1逐步增加后续元素的值。最终的结果Stream中不包含第二个参数,该参数只用于表示序列的上界。
rangeClosed(int startInclusive, int endInclusive) 方法作用是相同的,只有一点区别——结果Stream中包含第二个参数。这两个方法可以用于生成基本类型的流。
从Java 8开始,Random类为生成基本类型流提供了一些方法。例如,以下代码创建一个DoubleStream,其中包含三个元素:
Random random = new Random();
DoubleStream doubleStream = random.doubles(3);
字符串Stream
字符串也可以作为创建流的源。
通过使用String类中的chars()方法可以得到一个字符流。由于JDK中没有定义CharStream接口,可