是否存在'reduce'的类型安全的Java实现?

时间:2022-01-22 16:01:43

I often need to run reduce (also called foldl / foldr, depending on your contexts) in java to aggregate elements of an Itterable.

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

Reduce takes a collection/iterable/etc, a function of two parameters, and an optional start value (depending on the implementation details). The function is successively applied to an element of the collection and the output of the previous invocation of reduce until all elements have been processed, and returns the final value.

Reduce采用集合/可迭代/ etc,两个参数的函数和可选的起始值(取决于实现细节)。该函数连续应用于集合的元素和先前调用的输出reduce,直到处理完所有元素,并返回最终值。

Is there a type-safe implementation of reduce in any common java api? Google Collections seems like it should have one, but I haven't been able to find it. (possibly because I don't know what other names it would use.)

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

3 个解决方案

#1


2  

you could probably roll your own generic pretty easily, based on your description:

你可以根据你的描述很容易地推出你自己的通用:

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

Then using the strategy pattern:

然后使用策略模式:

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

I'm sure there are a ton of syntax errors but that's the main point (there a few choices you could make about how to get the empty accumulator value. Then to use it on a particular iterator just define your Reducer on the fly:

我确定有大量的语法错误,但这是主要的一点(你可以选择如何获得空的累加器值。然后在特定的迭代器上使用它只需动态定义你的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());

depending on how your iterator works this can fold left or fold right as long as the iterator goes in the right direction.

根据迭代器的工作原理,只要迭代器向右移动,它就可向左折叠或向右折叠。

hope this helps.

希望这可以帮助。

#2


2  

Based on Luke's suggestion, here is a legit Java implementation:

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

#3


1  

Try the commons functor package. It's been in sandbox forever, but I think it'll do what you want.

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

#1


2  

you could probably roll your own generic pretty easily, based on your description:

你可以根据你的描述很容易地推出你自己的通用:

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

Then using the strategy pattern:

然后使用策略模式:

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

I'm sure there are a ton of syntax errors but that's the main point (there a few choices you could make about how to get the empty accumulator value. Then to use it on a particular iterator just define your Reducer on the fly:

我确定有大量的语法错误,但这是主要的一点(你可以选择如何获得空的累加器值。然后在特定的迭代器上使用它只需动态定义你的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());

depending on how your iterator works this can fold left or fold right as long as the iterator goes in the right direction.

根据迭代器的工作原理,只要迭代器向右移动,它就可向左折叠或向右折叠。

hope this helps.

希望这可以帮助。

#2


2  

Based on Luke's suggestion, here is a legit Java implementation:

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

#3


1  

Try the commons functor package. It's been in sandbox forever, but I think it'll do what you want.

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