Java系列-StreamApi

Java Stream 简介

Java8 中的 Stream 是对集合(Collection) 对象功能的增强,它专注于对集合对象进行各种便利、高效的聚合操作,
或者是大批量的数据操作。Stream Api 的引入是为了弥补 Java 函数式编程的不足。但是这些 Api 并没有在集合类实现,
而是定义了全新的Stream APi。有几个重要的原因:

  • 集合类的所有元素都存储在内存中,非常大的集合类将占据大量的内存,但是 Stream 只有在执行结束操作(terminal)的
    时候才会真正的进行计算(稍后会提到)。

  • 另外还有集合类的迭代逻辑通常是通过 for 来负责的,但是 Stream 的迭代是隐含在对 Stream 的各种操作中,例如
    map(), reduce()。

创建一个流有很多的方法,例如:


    Collection.stream();
    Collection.parallelStream();
    Arrays.stream(T array) or Stream.of();

一个流可以进行多种操作,总的来说,流的操作分为三类:

  • 中间操作: 一个流可以有零个或者多个中间操作,是为了打开流,作出某种程度的数据映射和过滤,然后返回一个新的流(每次转
    换原有的 Stream 对象不变,会返回转变后的一个新的对象),也就是说,进行这类操作并没有真正开始流的遍历,典型的中间操作
    有:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、
    sequential、 unordered。

  • 结束操作: 一个流只能有一个结束操作,进行这个操作之后,这个流也就结束了,无法进行其他的中间操作或者结束操作,也就是
    说结束操作使得流进行了真正的遍历,典型的结束操作有:forEach、 forEachOrdered、 toArray、 reduce、 collect、
    min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator。

  • 短路操作:因为 Stream 有另外的一个特性,就是 可以存在无限的流。而短路操作正是用来处理这些情况。对于中间操作,如果
    接受的是一个无限大的 Stream, 短路操作可以帮助返回一个有限的新的 Stream。对于结束操作,如果接受的十一个无限大的
    Stream,短路操作可以帮助在有限的时间内计算出结果,典型的短路操作有:anyMatch、 allMatch、 noneMatch、
    findFirst、 findAny、 limit。

Java Stream 应用

一个简单的 Stream 例子:

    public static void main(String[] args) {

        List<Integer> numbers = Arrays.asList(1,45,9,34,78,19,65,76);

        numbers.stream()
                .filter((i) -> i%2 ==0)
                .map((i) -> i * i)
                .forEach(System.out::println);
    }

生成一个无限流,并且取出有限的个数:

    public class NumberStream implements Supplier<Long> {

      long value = 0;

      @Override
      public Long get() {
          this.value = this.value + 1;

          return this.value;
      }


      public static void main(String[] args) {

          Stream<Long> numbers = Stream.generate(new NumberStream());

          numbers.map((x) -> x * x ).skip(100).limit(10).forEach(System.out::println);
      }
    }


©2024 Rayjun    PowerBy Hexo