是否有“reduce”的类型安全 Java 实现?

发布于 2024-07-07 06:41:22 字数 357 浏览 7 评论 0原文

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

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

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

I often need to run reduce (also called foldl / foldr, depending on your contexts) in java to aggregate elements of an 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.

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

分分钟 2024-07-14 06:41:22

根据您的描述,您可能可以很容易地推出自己的泛型:

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

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

希望这会有所帮助。

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:

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.

林空鹿饮溪 2024-07-14 06:41:22

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

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

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;
}
深海蓝天 2024-07-14 06:41:22

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文