Java 8-Stream API-创建流

  • 使用stream方法从集合生成流
  • 由值创建流

可以使用静态方法Stream.of,通过显示值创建一个流。它可以接受任意数量的参数。

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

可以使用empty得到一个空流

Stream emptyStream=Stream.empty();
  • 由数组创建流

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

int[] numbers={2,3,5,7,11,13};
int sum=Arrays.stream(numbers).sum();
  • 由文件生成流

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

long uniqueWords=0;
try(Stream lines= Files.lines(Paths.get("a.txt"), Charset.defaultCharset())){
    uniqueWords=lines.flatMap(line-> Arrays.stream(line.split(" ")))
        .distinct()
        .count();
}catch (IOException e){

}

可以使用Files.lines得到一个流,其中的每个元素都是给定文件中的一行。

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

Stream API提供了两个静态方法来从函数生成流:Stream.iterate和Stream.generate。这两个操作可以创建所谓的无限流:不像从固定集合创建的流那样有固定大小的流。由iterate和generate产生的流会用给定的函数按需创建值,因此可以无穷无尽地计算下去。一般来说,应该使用limit(n)来对这种流加以限制,以避免打印无穷多个值。

1.迭代

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

iterate方法接受一个初始值(在这里是0),还有一个依次应用在每个产生的新值上的Lambda(UnaryOperator类型)。这里,我们使用Lambda n->n+2,返回的是前一个元素加上2。因此,iterate方法生成了一个所有正偶数的流:流的第一个元素是初始值0。然后加上2来生成新的值2,在加上2来得到新的值4,以此类推。这种iterate操作基本上是顺序的,因为结果取决于前一次应用。

此操作将生成一个无线流—这个流没有结尾,因为值是按需计算的,可以永远计算下去。这个流时无界的,这是流和集合之间的一个关键区别。

在需要依次生成一系列值的时候应该使用iterate,比如一系列日期:1月31日,2月1日。

斐波纳契元组序列

斐波纳契数列,0,1,1,2,3,5,8,13,21,34…数列中开始的两个数字是0和1,后续的每个数字都是前两个数字之和。

斐波纳契元组数列与此类似,是数列中数字和其后续数字组成的元组构成的序列:(0,1),(1,1),(1,2),(2,3),(3,5),(5,8)…

Stream.iterate(new int[]{0,1},
              t->new int[]{t[1],t[0]+t[1]})
    .limit(20)
    .forEach(t->System.out.println("("+t[0]+","+t[1]+")"));

2.生成

generate不是依次对每个新生成的值应用函数。它接受一个Supplier类型的Lambda提供新的值。

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

将生成5个0到1之间的随机双精度数。

你可能感兴趣的:(Java 8-Stream API-创建流)