考虑一个问题,我正在开发像Collection这样的树。
我的收藏集的主要功能之一是逐个跟踪所有存储的项目,然后为每个项目调用给定的功能,直到给定的标准为止遇见(懒人收藏)。
因此该函数应具有以下签名:
void Trace(function func, criteria crit)
{
item i = firstItem();
while (i != endItem())
{
i = nextItem();
func(i);
if (crit(i))
return;
}
}
C++
函数指针中的可用于func
和crit
在C#
中,yield
关键字正是这个问题的解决方案,我相信。
如何在Java中获得相同的东西?
答案 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对象。在这里,您的算法是您要传递的func
和crit
函数。
所以,你有一个名为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中正常工作:
func
和crit
应该是实现特定接口的对象实例。然后,您可以在对象i
上调用此接口中的函数。实际上,这是一个具有两个不同的电阻参数的Vistor模式。Iterator
- 这为您提供了一种遍历整个结构的好方法。或者你可以使trace
递归(它在树的左右分支上调用它),然后你就不需要迭代器。迭代器版本看起来像这样:
public void trace(IFunction func, ICriteria crit) {
for (T i: this) {
func.call(i);
if (crit.test(i)) return;
}
}
此处T
是集合的项类型,call
和test
分别是IFunction
和ICriteria
接口中的函数定义。 / p>