Java中的Lazy Collection

时间:2012-12-28 01:20:17

标签: java collections

考虑一个问题,我正在开发像Collection这样的树。

我的收藏集的主要功能之一是逐个跟踪所有存储的项目,然后为每个项目调用给定的功能,直到给定的标准为止遇见(懒人收藏)。

因此该函数应具有以下签名:

void Trace(function func, criteria crit)
{
    item i = firstItem();
    while (i != endItem())
    {
        i = nextItem();
        func(i);
        if (crit(i))
            return;
    }
}
C++函数指针中的

可用于funccritC#中,yield关键字正是这个问题的解决方案,我相信。

如何在Java中获得相同的东西?

4 个答案:

答案 0 :(得分:2)

在Java中,您可以将引用传递给实现适用函数的类的对象,或者使用Commons Collections:

例如:

Closure c = new Closure() {
    public void execute(Object obj) {
        ...
    }
};

Predicate p = new Predicate() {
    public boolean evaluate(Object obj) {
        ...
    }
}

Trace(c, p);

答案 1 :(得分:2)

您在这里寻找的是Strategy设计模式。

此模式的目标是将算法的实现抽象为Strategy对象。在这里,您的算法是您要传递的funccrit函数。

所以,你有一个名为TraceStrategy的界面。然后,您将此接口的实现传递到您的集合中。您的代码看起来像

void Trace(TraceStrategy traceStrategy)
{
    item i = firstItem();
    while (i != endItem())
    {
        i = nextItem();
        traceStrategy.func(i);
        if (traceStrategy.crit(i))
            return;
    }
}

interface TraceStrategy {
   public boolean crit(item i);

   public void func(item i);
}

你可能想要使这个通用,所以你没有被绑定到item ......但你明白了。

答案 2 :(得分:1)

创建一个声明方法的接口,并且需要引用实现接口的对象作为参数。调用者可以使用匿名内部类创建对象。

答案 3 :(得分:1)

通过结合几种技术,您可以使这个trace函数在Java中正常工作:

  • 而不是"函数指针",您的参数funccrit应该是实现特定接口的对象实例。然后,您可以在对象i上调用此接口中的函数。实际上,这是一个具有两个不同的电阻参数的Vistor模式。
  • 您还需要一些方法来遍历树。您可以实现Iterator - 这为您提供了一种遍历整个结构的好方法。或者你可以使trace递归(它在树的左右分支上调用它),然后你就不需要迭代器。

迭代器版本看起来像这样:

public void trace(IFunction func, ICriteria crit) {
    for (T i: this) {
        func.call(i);
        if (crit.test(i)) return;
    }
}

此处T是集合的项类型,calltest分别是IFunctionICriteria接口中的函数定义。 / p>