建设ca网站,旅游网站设计与建设论文,有可以做ssgsea的网站么,免费模板的软件比尔盖茨曾经说过#xff1a;“我选择一个懒惰的人去做一件困难的事情#xff0c;因为一个懒惰的人会找到一个简单的方法来做。” 关于流#xff0c;没有什么比这更真实了。 在本文中#xff0c;您将学习Stream如何通过在调用终端操作之前不对源元素执行任何计算来避免不必… 比尔·盖茨曾经说过“我选择一个懒惰的人去做一件困难的事情因为一个懒惰的人会找到一个简单的方法来做。” 关于流没有什么比这更真实了。 在本文中您将学习Stream如何通过在调用终端操作之前不对源元素执行任何计算来避免不必要的工作以及源如何只生成最少数量的元素。 本文是五分之三以GitHub存储库为补充其中包含每个单元的说明和练习。 第1部分创建流 第2部分中级操作 第三部分终端操作 第4部分数据库流 第5部分使用流创建数据库应用程序 终端机操作 现在我们熟悉Stream管道的初始化和构造我们需要一种处理输出的方法。 终端操作通过从其余元素例如 count() 或副作用例如 forEach(Consumer) 。 在启动终端操作之前Stream将不会对源的元素执行任何计算。 这意味着仅在需要时才使用源元素这是避免不必要工作的明智方法。 这也意味着一旦应用了终端操作流将被消耗并且无法再添加其他操作。 让我们看一下可以应用于Stream管道末尾的哪些终端操作 ForEach和ForEachOrdered 流的可能用例可能是更新某些或所有元素的属性或者为什么不只是出于调试目的而将它们打印出来。 无论哪种方式我们都不希望收集或计数输出而是通过产生副作用而不返回值来进行。 这是目的 forEach()或 forEachOrdered() 。 他们俩都 Consumer并终止Stream而不返回任何内容。 这些操作之间的区别仅仅是 forEachOrdered()承诺按照元素在Stream中出现的顺序调用提供的Consumer。 forEach()仅承诺以任何顺序调用Consumer。 后一种变体对并行流很有用。 在下面的简单情况下我们在一行中打印出Stream的每个元素。 Stream.of( Monkey , Lion , Giraffe , Lemur , “Lion” ) .forEachOrdered(System.out::print); 这将产生以下输出 MonkeyLionGiraffeLemurLion br 收集元素 Streams的常见用法是构建元素的“存储桶”或更具体地说构建包含特定元素集合的数据结构。 这可以通过调用终端操作来完成 Stream末尾的collect() 因此要求它将元素收集到给定的数据结构中。 我们可以提供称为 Collector collect()操作可以根据手头的问题使用许多不同的预定义类型。 以下是一些非常有用的选项 收集到设置 我们可以将所有元素收集到 通过使用收集器收集Stream的元素来简单地进行Set toSet() 。 SetString collectToSet Stream.of( Monkey , Lion , Giraffe , Lemur , Lion ) .collect(Collectors.toSet()); toSet: [Monkey, Lion, Giraffe, Lemur] 收集到清单 同样可以将元素收集到 List使用 toList()收集器。 ListString collectToList Stream.of( Monkey , Lion , Giraffe , Lemur , Lion ) .collect(Collectors.toList()); collectToList: [Monkey, Lion, Giraffe, Lemur, Lion] 收集到一般收藏 在更一般的情况下可以将Stream的元素收集到任何 通过仅提供所需构造函数的Collection Collection类型。 构造函数的例子是 LinkedList::new LinkedHashSet::new和 PriorityQueue::new LinkedListString collectToCollection Stream.of( Monkey , Lion , Giraffe , Lemur , Lion ) .collect(Collectors.toCollection(LinkedList:: new )); collectToCollection: [Monkey, Lion, Giraffe, Lemur, Lion] 收集到阵列 由于数组是固定大小的容器而不是灵活的容器 Collection 有充分的理由进行特殊的终端操作 toArray() 以将元素创建并存储在Array中。 请注意仅调用toArray()会导致Objects Array 因为该方法无法自行创建类型化数组。 下面我们展示如何使用String数组的构造函数来提供类型化的数组String[] 。 String[] toArray Stream.of( Monkey , Lion , Giraffe , Lemur , Lion ) .toArray(String[]:: new ); toArray: [Monkey, Lion, Giraffe, Lemur, Lion] 收集到地图 我们可能想从元素中提取信息并将结果提供为Map 。 为此我们使用收集器toMap() 它需要两个 Functions按键对应的映射器和值映射器。 该示例显示了不同的动物如何与它们名称中不同字符的数量相关联。 我们使用中间操作distinct()来确保仅在Map添加唯一键如果键不是唯一的则必须提供toMap()收集器的变体其中必须提供用于合并的解析器来自相等键的结果。 MapString, Integer toMap Stream.of( Monkey , Lion , Giraffe , Lemur , Lion ) .distinct() .collect(Collectors.toMap( Function.identity(), //FunctionString, K keyMapper s - ( int ) s.chars().distinct().count() // FunctionString, V valueMapper )); toMap: {Monkey 6 , Lion 4 , Lemur 5 , Giraffe 6 } (*) *请注意键顺序是未定义的。 收集分组 坚持使用桶的类比我们实际上可以同时处理多个桶。 有一个非常有用的Collector名为 groupingBy()根据某些属性将元素划分为不同的组从而通过称为“分类器”的某种内容提取该属性。 这样的操作的输出是Map 。 下面我们演示如何根据动物的名字的首字母对动物进行分组。 MapCharacter, ListString groupingByList Stream.of( Monkey , Lion , Giraffe , Lemur , Lion ) .collect(Collectors.groupingBy( s - s.charAt( 0 ) // FunctionString, K classifier )); groupingByList: {G[Giraffe], L[Lion, Lemur, Lion], M[Monkey]} 使用下游收集器收集分组 在前面的示例中默认情况下将“下游收集器” toList()应用于Map的值将每个存储桶的元素收集到List 。 有一个重载版本的groupingBy() 它允许使用自定义的“下游收集器”来更好地控制生成的Map 。 下面是一个示例说明如何将特殊的下游收集器counting()用于计数而不是收集每个存储区的元素。 MapCharacter, Long groupingByCounting Stream.of( Monkey , Lion , Giraffe , Lemur , Lion ) .collect(Collectors.groupingBy( s - s.charAt( 0 ), // FunctionString, K classifier counting() // Downstream collector )); groupingByCounting: {G 1 , L 3 , M 1 } 这是该过程的说明 任何收集器都可以用作下游收集器。 特别是值得注意的是收集器groupingBy()可以采用下游收集器该下游收集器也是groupingBy()收集器从而允许对第一分组操作的结果进行二次分组。 在我们的动物案例中我们也许可以创建一个MapCharacter, MapCharacter, Long 其中第一个地图包含具有第一个字符的键第二个地图包含第二个字符作为键出现次数作为值。 元素的出现 中间操作filter()是消除与给定谓词不匹配的元素的好方法。 尽管在某些情况下我们只是想知道是否存在至少一个满足该谓词的元素。 如果是这样使用anyMatch()会更方便和有效。 在这里我们寻找数字2的出现 boolean containsTwo IntStream.of( 1 , 2 , 3 ).anyMatch(i - i 2 ); containsTwo: true 计算操作 几个终端操作输出计算结果。 我们可以执行的最简单的计算是count() 它可以应用于任何 Stream. 例如它可以用于计算动物数量 long nrOfAnimals Stream.of( Monkey , Lion , Giraffe , Lemur ) .count(); nrOfAnimals: 4 虽然某些终端操作仅适用于我们在第一篇文章中提到的特殊Stream实现。 IntStream LongStream和DoubleStream 。 可以访问此类流我们可以简单地将所有元素汇总如下 int sum IntStream.of( 1 , 2 , 3 ).sum(); sum: 6 或者为什么不使用.average()计算整数的平均值 OptionalDouble average IntStream.of( 1 , 2 , 3 ).average(); average: OptionalDouble[ 2.0 ] 或使用.max()检索最大值。 int max IntStream.of( 1 , 2 , 3 ).max().orElse( 0 ); max: 3 像average()一样 max()运算符的结果是Optional 因此通过声明.orElse(0)我们自动检索该值如果存在或默认为0。 如果我们宁愿处理原始返回类型也可以将相同的解决方案应用于平均示例。 如果我们对所有这些统计数据都感兴趣那么创建几个相同的流并对每个流应用不同的终端操作是非常麻烦的。 幸运的是有一个方便的操作称为summaryStatistics() 它允许将几个常见的统计属性合并到一个 SummaryStatistics对象。 IntSummaryStatistics statistics IntStream.of( 1 , 2 , 3 ).summaryStatistics(); statistics: IntSummaryStatistics{count 3 , sum 6 , min 1 , average 2.000000 , max 3 } 练习题 希望您现在熟悉所提供练习的格式。 如果您只是发现了该系列或者最近才感到有点懒惰也许您也有自己的理由我们建议您克隆GitHub存储库并开始使用后续材料。 本文的内容足以解决名为MyUnit3Terminal的第三个单元。 相应的Unit3Terminal接口包含JavaDocs它们描述MyUnit3Terminal方法的预期实现。 public interface Unit3Terminal { /** * Adds each element in the provided Stream * to the provided Set. * * An input stream of [A, B, C] and an * empty input Set will modify the input Set * to contain : [A, B, C] * * param stream with input elements * param set to add elements to */ void addToSet(Stream stream, Set set); br 提供的测试例如Unit3MyTerminalTest将充当自动评分工具让您知道您的解决方案是否正确。 下一篇 下一篇文章将展示如何将到目前为止我们积累的所有知识应用于数据库查询。 提示再见SQLHello Streams…直到那时–编码愉快 s Per Minborg Julia·古斯塔夫森Julia Gustafsson 翻译自: https://www.javacodegeeks.com/2019/10/become-master-java-streams-terminal-operations.html