迭代函数

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)

而且我想避免写出数百行函数调用.

我已经尝试过研究函数指针和仿函数,但没有找到任何相关的东西.

Chr*_*ung 6

您不能使用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)