1 java function-pointers functor
这样的事情可以用Java做吗?
for (Object o : objects) {
for (Function f : functions) {
f(o);
}
}
Run Code Online (Sandbox Code Playgroud)
我只调用了一些函数,但我需要编写它们,如下所示:
for (Object o : objects) {
for (Function f : functions) {
for (Function g : functions) {
f(g(o));
}
}
}
Run Code Online (Sandbox Code Playgroud)
而且我想避免写出数百行函数调用.
我已经尝试过研究函数指针和仿函数,但没有找到任何相关的东西.
您不能使用f(g(o))
语法,但可以使用(使用合适的接口)f.call(g.call(o))
.
public interface UnaryFunction<Arg, Ret> {
Ret call(Arg arg);
}
Run Code Online (Sandbox Code Playgroud)
示例用法(这与Java中的仿函数一样接近,至少在闭包进入语言之前):
public class Exp implements UnaryFunction<Double, Double> {
public Double call(Double arg) {
return Math.exp(arg);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不想创建数量众多的类,基于反射的方法可能会更好(例如double
- > double
函数java.lang.Math
,但很容易适应其他场景):
public class MathUnary implements UnaryFunction<Double, Double> {
private final Method method;
public MathUnary(String funName) {
try {
method = Math.class.getMethod(funName, double.class);
} catch (NoSuchMethodException exc) {
throw new IllegalArgumentException(exc);
}
if (method.getReturnType() != double.class)
throw new IllegalArgumentException();
}
public Double call(Double arg) {
try {
return (Double) method.invoke(null, arg);
} catch (IllegalAccessException exc) {
throw new AssertionError(exc);
} catch (InvocationTargetException exc) {
throw new AssertionError(exc);
}
}
}
Run Code Online (Sandbox Code Playgroud)
(为简洁起见,省略了异常消息.显然,我会将它们放入生产代码中.)
样品用法:
MathUnary[] ops = {
new MathUnary("sin"), new MathUnary("cos"), new MathUnary("tan")
};
for (UnaryFunction<Double, Double> op1 : ops) {
for (UnaryFunction<Double, Double> op2 : ops) {
op1.call(op2.call(arg));
}
}
Run Code Online (Sandbox Code Playgroud)