【问题标题】:Is there a type-safe Java implementation of 'reduce'?是否有“reduce”的类型安全 Java 实现?
【发布时间】:2010-09-18 09:22:54
【问题描述】:

我经常需要在 java 中运行 reduce(也称为 foldl / foldr,具体取决于您的上下文)来聚合 Itterable 的元素。

Reduce 接受一个集合/可迭代/等,一个由两个参数组成的函数,以及一个可选的起始值(取决于实现细节)。该函数依次作用于集合的一个元素和上一次reduce调用的输出,直到所有元素都被处理完,并返回最终值。

在任何常见的 java api 中是否有类型安全的 reduce 实现? Google Collections 似乎应该有一个,但我一直没能找到它。 (可能是因为我不知道它会使用什么其他名称。)

【问题讨论】:

    标签: java collections reduce


    【解决方案1】:

    试试commons functor package。它一直在沙盒中,但我认为它会做你想做的事。

    【讨论】:

    • 这看起来很有趣,但它看起来不太适合现有的 Java 集合库。如果没有其他结果,我会更深入地研究它。
    • 是的,这很复杂。我想你可以用它做朱丽叶薯条。看起来与集合集成的关键是 IteratorToGeneratorAdapter 类。
    【解决方案2】:

    根据您的描述,您可能很容易推出自己的通用名称:

    public interface Reducer<A, T>
    {
        public A foldIn(A accum, T next);
    }
    

    然后使用策略模式:

    public class Reductor<A, T>
    {
        private Reducer<A, T> worker;
        public Reductor<A, T>(Reducer<A, T> worker)
        {
            this.worker = worker;
        }
    
        public A fold(A rval, Iterator<T> itr)
        {
            while(itr.hasNext())
            {
                A rval = worker.foldIn(rval, itr.next());
            }
            return rval;
        }
    }
    

    我确定存在大量语法错误,但这是重点(您可以选择一些关于如何获取空累加器值的选择。然后在特定迭代器上使用它,只需在飞:

    Reductor r = new Reductor<A, T>(new Reducer<A, T>()
    {
        public A foldIn(A prev, T next)
        {
            A rval;
           //do stuff...
           return rval;
         }
     }
    
     A fold = r.fold(new A(), collection.getIterator());
    

    根据您的迭代器的工作方式,只要迭代器朝着正确的方向前进,它就可以向左折叠或向右折叠。

    希望这会有所帮助。

    【讨论】:

    • 这是一种解决方法——我还不相信我需要一个普遍适用的 reduce 版本,足以证明开发/测试/维护我自己的版本的成本是合理的。
    • 做得很好,但是你需要在java中做这件事的扭曲足以让我哭泣。
    • 认为将会有一个 Google Collections 的配套库提供这样的函数式语言工具,但目前,这是我找到的最佳答案。
    【解决方案3】:

    根据 Luke 的建议,这是一个合法的 Java 实现:

    public interface Reducer<A,T>
    {
        A foldIn(A accum, T next);
    }
    
    public static <T> T reduce(final Reducer<T,T> reducer, 
            final Iterable<? extends T> i)
    {
        T result = null;
        final Iterator<? extends T> iter = i.iterator();
        if (iter.hasNext())
        {
            result = iter.next();
            while (iter.hasNext())
            {
                result = reducer.foldIn(result, iter.next());
            }
        }
        return result;
    }
    
    public static <A,T> A reduce(final Reducer<A,T> reducer, 
            final Iterable<? extends T> i, 
            final A initializer)
    {
        A result = initializer;
        final Iterator<? extends T> iter = i.iterator();
        while (iter.hasNext())
        {
            result = reducer.foldIn(result, iter.next());
        }
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 2021-07-17
      • 2016-04-16
      相关资源
      最近更新 更多