7

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

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

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

4

3 回答 3

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;
    }
}

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

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());

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

希望这可以帮助。

于 2008-10-21T19:26:24.177 回答
2

根据 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;
}
于 2010-06-21T20:45:21.630 回答
1

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

于 2008-10-21T18:59:15.870 回答