【问题标题】:Java 8 Stream API min() and max() vs Collectors minBy() and maxBy() [duplicate]Java 8 Stream API min() 和 max() 与收集器 minBy() 和 maxBy() [重复]
【发布时间】:2021-06-16 08:11:03
【问题描述】:

在 java 8 中,Stream API 帮助我们以非常干净和更少的代码来完成我们的工作。我是这些流 API 的忠实粉丝。但是很少有操作哪种有助于解决同一类型的问题,并且不确定何时使用哪种操作虽然选择起来并不难,但只是想知道任何人对这些有任何特定的用例。我所说的操作是:-

中间操作:- minmax

终端操作:collectCollectors 使用 minBymaxBy 的类策略

List<String> randomString= Arrays.asList("AA","AAA","A","AAAA","AAAAAA","AAAAAAAAAAAAAAAAAA");
String maxByIntermediateMax = randomString.stream().max(String :: compareTo).get();
String minByIntermediateMin = randomString.stream().min(String :: compareTo).get();
System.out.println("Intermediate Min() :- "+minByIntermediateMin+" Intermeidate Max() :- "+ maxByIntermediateMax);
String minByCollectorsMinBy = randomString.stream().collect(Collectors.minBy(Comparator.naturalOrder())).get();
String maxByCollectorsMaxBy = randomString.stream().collect(Collectors.maxBy(Comparator.naturalOrder())).get();
System.out.println("Collectors MinBy :- "+minByCollectorsMinBy+ " , Collectors maxBy is :- "+maxByCollectorsMaxBy);

输出

Intermediate Min() :- A Intermeidate Max() :- AAAAAAAAAAAAAAAAAA
Collectors MinBy :- A , Collectors maxBy is :- AAAAAAAAAAAAAAAAAA

【问题讨论】:

  • Collectors.summingInt() vs mapToInt().sum()中的考虑基本相同,顺便说一句,当您已经了解Comparator.naturalOrder()时,无需通过String :: compareTo创建新的比较器。
  • ... 至少除非有任何可以证明的性能优势。

标签: java java-8 java-stream collectors


【解决方案1】:

Stream#min 的 JavaDoc 说min 是一个终端操作,所以.collect(Collectors.minBy(...)).min(...) 可以互换。

就我而言,minmax 的语法更易读,但collect 更通用,因此作为示例,您可以将 min/max 收集器作为方法的参数传递。

【讨论】:

    【解决方案2】:

    使用stream().max 可以有效地产生与stream().collect(Collectors.maxBy) 相同的结果。 stream().minstream().collect(Collectors.minBy) 也是如此

    虽然结果相同,但这两种方法在可读性和灵活性方面存在一些细微差别。

    通过使用收集器,您可以使用任何返回Optional&lt;String&gt; 的收集器。实现的minmax 只是Collectors.reducing 的一些实现版本。您也可以使用与Collectors.reducing 类似的任何其他Collector 作为参数。

     List<String> randomString= Arrays.asList("AA","AAA","A","AAAA","AAAAAA","AAAAAAAAAAAAAAAAAA");
     Collector<String, ?, Optional<String>> collectorMin = Collectors.minBy(Comparator.naturalOrder());
     Collector<String, ?, Optional<String>> collectorMax = Collectors.minBy(Comparator.naturalOrder());
        
         
        String collectedMin= randomString.stream().collect(collectorMin ).get();
        String collectedMax= randomString.stream().collect(collectorMax ).get();
    

    另一方面,stream().max/stream().min 更易读,更简洁。

    【讨论】:

      【解决方案3】:

      Stream.minStream.max终端 操作。 javadoc 清楚地说明了这一点。

      这两者之间的相似之处是您在问题中提到的。他们都使用BinaryOperator.minBy(comparator) 对元素进行reducing 操作(尽管减少的实现方式略有不同)。

      因此,您的代码中的输出没有变化。由于您需要在所有流元素中找到最小值/最大值,我建议您使用Stream.min,因为代码看起来很整洁,而且在这种情况下您实际上不需要创建收集器。

      但有些场景需要使用Collectors.minBy。假设您需要对元素进行分组,并且需要在每个组中找到最小值/最大值。在这种情况下,您不能使用Stream.min。这里需要使用Collectors.groupingBy(mapper, Collectors.minBy(...))。同样,您可以将它用于partitionBy 和其他需要收集器的类似方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-23
        • 2017-06-16
        • 2017-09-08
        • 1970-01-01
        • 2014-06-11
        • 1970-01-01
        • 1970-01-01
        • 2014-04-28
        相关资源
        最近更新 更多