【问题标题】:What is the Java equivalent to Python's reduce function?什么是 Java 等价于 Python 的 reduce 函数?
【发布时间】:2015-01-08 14:03:06
【问题描述】:

已经提出了类似的问题,herehere,但考虑到 Java 8 的出现,以及这些问题的普遍过时性质,我想知道现在是否至少有类似的问题?

This 是我指的。

【问题讨论】:

  • Stream.reduce,也许?还可以考虑Stream.collect,它为许多用例提供了更好的性能。
  • 虽然是等价的,但 Java 的 reduce 不如 Python 的通用。例如,您不能提供不同类型的初始值并根据当前结果和流中的元素顺序减少。因为您还需要提供一个组合器双功能,它应该提供一致的结果,例如a+b=b+a.

标签: java python function lambda functional-programming


【解决方案1】:

您可以使用 lambda 和 Stream.reduce,文档中有一个页面专门用于 reductions

Integer totalAgeReduce = roster
   .stream()
   .map(Person::getAge)
   .reduce(
       0,
       (a, b) -> a + b);

【讨论】:

    【解决方案2】:

    这是用 Java 8 流实现的 example used in the Python docs

    List<Integer> numbers = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5 });
    Optional<Integer> sum = numbers.stream().reduce((a, b) -> a + b);
    System.out.println(sum.get());
    

    【讨论】:

    • @zehnpaard reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 来自页面 OP linked to
    • 啊抱歉我误会了,我以为你的意思是 Java 代码出现在 Python 文档中的某个地方,可能是作为比较其他语言中类似技术的一部分。
    【解决方案3】:

    Stream.reduce 方法

    Stream.reduce 方法是一种通用的归约操作。考虑以下管道,它计算收集名册中男性成员年龄的总和。它使用 Stream.sum 归约操作:

     Integer totalAge = roster
         .stream()
        .mapToInt(Person::getAge)
        .sum();
    

    将此与以下管道进行比较,该管道使用 Stream.reduce 操作来计算相同的值:

    Integer totalAgeReduce = roster
       .stream()
       .map(Person::getAge)
       .reduce(
           0,
           (a, b) -> a + b);
    

    本例中的 reduce 操作有两个参数:

    identity:identity 元素既是归约的初始值,也是流中没有元素时的默认结果。在本例中,标识元素为 0;这是年龄总和的初始值,如果集合名册中不存在任何成员,则为默认值。

    accumulator:accumulator 函数有两个参数:归约的部分结果(在此示例中,为到目前为止所有已处理整数的总和)和流的下一个元素(在此示例中为整数)。它返回一个新的部分结果。在此示例中,累加器函数是一个 lambda 表达式,它将两个 Integer 值相加并返回一个 Integer 值:

    (a, b) -> a + b
    

    reduce 操作总是返回一个新值。但是,累加器函数在每次处理流的元素时也会返回一个新值。假设您要将流的元素简化为更复杂的对象,例如集合。这可能会妨碍您的应用程序的性能。如果您的 reduce 操作涉及将元素添加到集合中,那么每次您的累加器函数处理一个元素时,它都会创建一个包含该元素的新集合,这是低效的。相反,更新现有集合对您来说会更有效。您可以使用 Stream.collect 方法执行此操作,下一节将对此进行介绍。

    官方 oracle 教程描述了 Stream.reduce 的工作原理。请看一下,我相信它会回答您的问题。

    【讨论】:

      猜你喜欢
      • 2010-10-28
      • 1970-01-01
      • 2015-11-22
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 2013-09-26
      • 2014-07-21
      • 2011-01-04
      相关资源
      最近更新 更多