【问题标题】:Does guava have an equivalent to Python's reduce function?番石榴是否有等效于 Python 的 reduce 函数?
【发布时间】:2011-06-28 18:24:57
【问题描述】:

guava(或其他 java 库)在 Python 中有类似 reduce() 的函数吗?

我正在寻找这样的东西http://docs.python.org/library/functions.html#reduce

【问题讨论】:

标签: java guava functional-programming


【解决方案1】:

没有。最终可能会,尽管像这样的功能性东西并不是 Guava 的核心焦点。见this issue

【讨论】:

    【解决方案2】:

    我还没有找到任何支持mapreduce 的Java 集合库。 (我排除了并行/分布式处理框架中的 map/reduce 功能……因为您需要一个“大”问题才能使这些框架有价值。)

    这种“缺乏”的原因可能是没有闭包的 map/reduce 编码太麻烦了。太多样板代码,太多重量级语法。由于在简单集合上使用 map/reduce 原语的主要目的是让您的代码简单而优雅......


    @CurtainDog 提供了指向lambdaj 的链接。这就是 OP 所追求的(尽管没有专门称为reduce 的方法)。但它说明了我所说的样板。请注意,许多高阶操作涉及创建扩展 Closure 类中的一个或其他的类。

    (FWIW,我认为 Lambda.aggregate(...) 方法是 reduce 的 lambdaj 模拟。)

    【讨论】:

    【解决方案3】:

    Java 8 流允许您这样做。

    mylist.stream().map((x) -> x + 1).reduce((a,b) -> a + b)
    

    欲了解更多信息:http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

    【讨论】:

      【解决方案4】:

      我最近在submitted an issue 请求/讨论过类似的事情。这就是我的实现所需要的

      /**
       * Aggregate the selected values from the supplied {@link Iterable} using
       * the provided selector and aggregator functions.
       * 
       * @param <I>
       *            the element type over which to iterate
       * @param <S>
       *            type of the values to be aggregated
       * @param <A>
       *            type of the aggregated value
       * @param data
       *            elements for aggregation
       * @param selectorFunction
       *            a selector function that extracts the values to be aggregated
       *            from the elements
       * @param aggregatorFunction
       *            function that performs the aggregation on the selected values
       * @return the aggregated value
       */
      public static <I, S, A> A aggregate(final Iterable<I> data,
          final Function<I, S> selectorFunction,
          final Function<Iterable<S>, A> aggregatorFunction){
          checkNotNull(aggregatorFunction);
          return aggregatorFunction.apply(
              Iterables.transform(data, selectorFunction)
          );
      }
      

      (选择器函数可以从对象中拉取要聚合的值进行查询,但在很多情况下会是Functions.identity(),即对象本身就是聚合的对象)

      这不是经典的折叠,但需要Function&lt;Iterable&lt;X&gt;,X&gt; 才能完成这项工作。但由于实际代码是单行代码,因此我选择请求一些标准聚合器函数(我会将它们放在一个名为 AggregatorsAggregatorFunctions 甚至 Functions.Aggregators 之类的类中):

      /** A Function that returns the average length of the Strings in an Iterable. */
      public static Function<Iterable<String>,Integer> averageLength()
      
      /** A Function that returns a BigDecimal that corresponds to the average
          of all numeric values passed from the iterable. */
      public static Function<Iterable<? extends Number>,BigDecimal> averageOfFloats()
      
      /** A Function that returns a BigInteger that corresponds to the average
          of all numeric values passed from the iterable. */
      public static Function<Iterable<? extends Number>,BigInteger> averageOfIntegers()
      
      /** A Function that returns the length of the longest String in an Iterable. */    
      public static Function<Iterable<String>,Integer> maxLength()
      
      /** A Function that returns the length of the shortest String in an Iterable. */
      public static Function<Iterable<String>,Integer> minLength()
      
      /** A Function that returns a BigDecimal that corresponds to the sum of all
          numeric values passed from the iterable. */
      public static Function<Iterable<? extends Number>,BigDecimal> sumOfFloats()
      
      /** A Function that returns a BigInteger that corresponds to the integer sum
          of all numeric values passed from the iterable. */
      public static Function<Iterable<? extends Number>,BigInteger> sumOfIntegers()
      

      (您可以在问题中查看我的示例实现)

      这样,你可以做这样的事情:

      int[] numbers = { 1, 5, 6, 9, 11111, 54764576, 425623 };
      int sum = Aggregators.sumOfIntegers().apply(Ints.asList(numbers)).intValue();
      

      这绝对不是您所要求的,但在许多情况下它会更容易,并且会与您的请求重叠(即使方法不同)。

      【讨论】:

        【解决方案5】:

        Jedi 有一个reduce 操作。 Jedi 还通过使用注释为您生成仿函数来帮助减少样板。请参阅这些examples

        【讨论】:

          【解决方案6】:

          番石榴有transform(地图)。好像 reduce 不见了?

          【讨论】:

            【解决方案7】:

            我开发了一个库来使用标准 J2SE 进行映射/过滤/减少。 对不起,它是法语,但用谷歌翻译你可以阅读: http://caron-yann.developpez.com/tutoriels/java/fonction-object-design-pattern-attendant-closures-java-8/

            你可以这样使用:

            int sum = dogs.filter(new Predicate<Arguments2<Dog, Integer>>() {
            
                @Override
                public Boolean invoke(Arguments2<Dog, Integer> arguments) {
                    // filter on male
                    return arguments.getArgument1().getGender() == Dog.Gender.MALE;
                }
            }).<Integer>map(new Function<Integer, Arguments2<Dog, Integer>>() {
            
                @Override
                public Integer invoke(Arguments2<Dog, Integer> arguments) {
                    // get ages
                    return arguments.getArgument1().getAge();
                }
            }).reduce(new Function<Integer, Arguments2<Integer, Integer>>() {
            
                @Override
                public Integer invoke(Arguments2<Integer, Integer> arguments) {
                    // sum âges
                    return arguments.getArgument1() + arguments.getArgument2();
                }
            });
            
            System.out.println("Le cumul de l'âge des mâles est de : " + sum + " ans");
            

            享受这份帮助

            【讨论】:

              【解决方案8】:

              使用Totally Lazy,它实现了所有这些功能。 它基本上复制了Clojure的整个功能方法。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-01-21
                • 1970-01-01
                • 2019-02-13
                • 2011-05-10
                • 2013-07-14
                相关资源
                最近更新 更多