在以下代码中,您可以应用任何函数f(例如,加,减等)。我如何通过Java做到这一点?
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
答案 0 :(得分:7)
您需要对此代码进行两项主要更改,以使其在Java中运行。首先,您需要使用Java样式的迭代器替换STL样式的迭代器,幸运的是,这并不是太难。其次,您必须使用不同类型的对象更改函数指针或functor参数的使用,因为Java不支持函数指针。
在Java中,迭代器比C ++中更重,并且封装了它们遍历的整个范围,而不仅仅是该范围的开始或结束。使用Java迭代器,您可以使用.next()和.hasNext()方法遍历范围。
对于函数参数,您可能需要创建自己的接口来表示可以作为函数调用的对象。例如:
public interface Operation<T> {
void apply(T argument);
}
此接口是在某些类型T上参数化的通用参数,说明参数类型是什么,然后导出一个名为apply()的函数来应用该函数。
鉴于此,复制for_each的简单但天真的方法是编写
public static <T> forEach(Iterator<T> itr, Operation<T> op) {
while (itr.hasNext())
op.apply(itr.next());
}
我之所以说这是天真的原因是它没有正确使用有界通配符来扩展它的使用范围。一个更适合Java的版本就是这个:
public static <T> forEach(Iterator<T> itr, Operation<? super T> op) {
while (itr.hasNext())
op.apply(itr.next());
}
请参阅Java遗传学参考资料,了解其工作原理。
希望这有帮助!
答案 1 :(得分:0)
要实现您使用Java Generics
的模板类对于回调,您很可能想要创建Interface并将实现它的对象传递给Generic类,您可以在其中调用定义的方法。
答案 2 :(得分:0)
你应该使用接口,但是如果你想以困难的方式去做,使用reflection(没有经过测试,没有例外检查等等。但是你可以得到这个想法):
public void myFunction(Collection items, String methodName) {
foreach(Object o : items) {
Method method = o.getClass().getMethod(methodName);
method.invoke(o);
}
}
答案 3 :(得分:0)
通过良好的OO设计,从头到尾都是特定(实现接口)类型的对象,而f()会将该类型的对象(接口)作为参数,这样你就完成了 - 它非常像你写的。
如果您正在谈论在原语上进行,那么它将需要泛型,但此时您需要寻找更好的设计或更好的方法来做到这一点。
如果我们对您要解决的问题有更多了解以及我们可以提供更好建议的限制,那么您没有提供足够的信息来获得更详细的答案。