zoukankan      html  css  js  c++  java
  • Java 8学习之Stream API

    一个Stream表面上看与一个集合很类似,允许你改变和获取数据。但是实际上他与集合是有很大区别的:

    • Stream自己不会存储元素。元素可能被存储在底层的集合中,或者根据需要产生出来。
    • Stream操作符不会改变源对象。相反,他们会返回一个持有结果的新Stream。
    • Stream操作符可能是延迟执行的。意味着他们会等到需要结果的时候才执行。

    下面是一段如何并行统计长单词的代码:

    long count = words.parallelStream()
                .filter(w->w.length()>12).count();
    

    Stream遵循“做什么,而不是怎么去做”的原则。在我们的示例中,描述了需要做什么:获得长单词并对他们的个数进行统计。我们没有指定按照什么顺序,或者在哪个线程中做,他们都是理所当然发生的。相反,循环一开始就需要指定如何计算,因此就失去了优化的机会。

    当你使用Stream时,你会通过三个阶段来建立一个操作流水线。

    • 创建一个Stream
    • 在一个或多个步骤中,指定将初始Stream转换为另一个Stream的中间操作。
    • 使用一个终止操作来产生一个结果。该操作会强制它之前的延迟操作立即执行。在这之后,该Stream就不会再被使用了。

    在我们的示例中,通过stream或parallelStream方法创建Stream,再通过filter方法对其进行准换,而count就是终止操作。

    一、创建Stream

    下面展示几种创建Stream的方法:

    Stream<String> stream = Stream.of("aaa", "bbb", "ccc", "ddd");
    Stream<String> echos = Stream.generate(() -> "Echo");
    Stream<Double> randoms = Stream.generate(Math::random);
    Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO,
                                  n -> n.add(BigInteger.ONE));
    

    二、提取子流和组合流

    Stream.limit(n)会返回一个包含n个元素的新流(如果原始流长度小于n,则会返回原始的流)。这个方法特别适用于剪裁指定长度的流。例如:

    Stream<Double> randoms = Stream.generate(Math::random).limit(100);
    

    会返回一个包含100个随机数字的流。

    Stream.skip(n)刚好相反,他会丢弃掉前面的n个元素。

    Stream.concat可以将两个流连接到一起。当然,第一个流的长度不应该是无限的,否则第二个流就永远没有机会被添加到第一个流的后面。

    三、简单的聚合方法

    • count会返回流中元素总数
    • max和min分别返回流中最大值和最小值
    • findFirst会返回非空集合的第一个值,它通常与filter方法结合使用。
    Optional<String> startWithQ = words.filter(s->s.startWith("Q")).findFirst();
    
    • 如果想找到所有匹配的元素,那么可以使用findAny方法。这个方法在对流进行并行执行时十分有效,因为只要在任何片段中发现了第一个匹配的元素,都会结束整个计算。
    Optional<String> startsWithQ
      = words.parallel().filter(s->s.startsWith("Q")).findAny();
    
    • 如果你只希望知道流中是否含有匹配元素,可以使用anyWatch方法。该方法可以接受一个predicate参数,因此你不需要filter方法。
    boolean aWordStartsWithQ
     = words.parallel().anyMatch(s->s.startsWith("Q"));
    
    • Java 8中还提供了两个方法allMatch和noneMatch,他们分别在所有元素和没有元素匹配predicate时返回true。虽然这些方法总是会检查整个流,但是仍可以通过并行执行来提高速度。

    四、Optional类型

    高效使用Optional的关键在于,使用一个或者接受正确值、或者返回另一个替代值的方法。

    创建可选值

    可以选择使用Optional.of(result)或者Optional.empty()来创建一个Optional对象。

    ofNullable方法被设计为null值和可选值之间的一座桥梁。如果obj不为null,那么Optional.ofNullable(obj)会返回Optional.of(obj),否则会返回Optional.empty()。

  • 相关阅读:
    完全背包
    二分求值(二分适合求答案在两个数之间的题目)
    set<pair<int,int> >的用法
    01背包 (dp专题)
    矩阵快速幂
    BZOJ1977 [BeiJing2010组队]次小生成树 Tree
    BZOJ1854 [Scoi2010]游戏
    BZOJ1054 [HAOI2008]移动玩具
    NOIP系列复习及题目集合
    BZOJ2708 [Violet 1]木偶
  • 原文地址:https://www.cnblogs.com/f-zhao/p/7367682.html
Copyright © 2011-2022 走看看