我经常需要在java中运行reduce(也称为foldl / foldr,具体取决于你的上下文)来聚合Itterable的元素。
Reduce采用collection / iterable / etc,两个参数的函数和一个可选的起始值(取决于实现细节)。该函数连续应用于集合的元素和之前调用的输出reduce,直到处理完所有元素,并返回最终值。
在任何常见的java api中是否存在类型安全的reduce实现? Google Collections 似乎它应该有一个,但我找不到它。 (可能是因为我不知道它会使用什么其他名称。)
答案 0 :(得分: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());
取决于迭代器的工作方式,只要迭代器向正确方向移动,它就可向左折叠或向右折叠。
希望这会有所帮助。
答案 1 :(得分: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;
}
答案 2 :(得分:1)
试试commons functor package。它永远存在于沙箱中,但我认为它会做你想要的。