模拟函数指针

以下类包含一个应使用回调技术计算积分的方法。

package integrals; import java.lang.*; public class Integrals { public static double f1(double x) { return x*5+Math.sin(x); } public static double f2(double x) { return Math.pow(x*f1(-x),x); } public static double TrapezoidalIntegration(double a,double b,int n,double (*f)(double)) { double rValue=0; double dx; dx=(ba)/n; for(double i=f(a);i<f(b);i+=dx) rValue+=((f(i)+f(i+dx))*dx)/2.0; return rValue; } public static void main(String[] args) { } } 

在这种情况下如何进行回调? 由于它的复杂性和丑陋性,我宁愿避免使用这种解决方案 。 即使它是最不痛苦的,我也不知道如何在这里实现它。

在这种情况下如何进行回调? 由于它的复杂性和丑陋性,我更愿意避免这种解决方案 。 即使它是最不痛苦的,我也不知道如何在这里实现它。

由于Java中没有函数指针,因此必须使用通用接口。 然后,您的function必须是该接口的实现。 是否要为那些实现类(即class F1 extends Function { … } )或匿名类(即new Function { … } )使用名称取决于您。 您是否在该类中编写impollementation,或者让类实现调用您现有的静态函数之一,也取决于您。

举一个例子,使用直接包含实现的匿名类:

 public class Integrals { public interface Function { double eval(double x); } public static final Function f1 = new Function() { public double eval(double x) { return x*5+Math.sin(x); } }; public static final Function f2 = new Function() { public double eval(double x) { return Math.pow(x*f1.eval(-x),x); } }; public static double TrapezoidalIntegration(double a,double b,int n,Function f) { // … using f.eval(x) to compute values 

此答案适用于不支持闭包或回调的Java 7或更低版​​本。

首先使用将计算积分值的方法定义抽象类或接口。 对于此示例,我将定义一个接口:

 interface IntegralCalculation { double getIntegralValue(double x); } 

在您的实际代码中,让我们替换接口的double (*f)(double)参数和要使用的方法:

 public static double TrapezoidalIntegration(double a,double b,int n, IntegralCalculation integralCalc) { double rValue; double dx; dx=(ba)/n; 

// for(int i = f(a); i

现在,在您的main方法(或您将调用此TrapezoidalIntegration方法的任何其他位置)中,传递接口的实现。 您可以传递实现接口的类的实例匿名类。

使用实现接口的类的类实例的示例(抱歉,不知道其他方式说出来):

 class BasicFunction implements IntegralCalculation { @Override public double getIntegralValue(double x) { return x*5+Math.sin(x); } } public class Integrals { public static void main(String[] args) { double x = TrapezoidalIntegration(0, 10, 10, new BasicFunction()); } } 

使用匿名类 :

 public class Integrals { public static void main(String[] args) { double x = TrapezoidalIntegration(0, 10, 10, new IntegralCalculation() { private double f1(double x) { return x*5+Math.sin(x); } @Override public double getIntegralValue(double x) { return Math.pow(x*f1(-x),x); } }); } } 

从上面的代码:

  • 您不能在Java中传递函数指针,因此double (*f)(double)参数将无效,而是使用抽象类或接口。 IMO界面会更好。
  • 设计完界面后,它必须有一个满足函数指针规则的方法。 在这种情况下, double (*f)(double)表示具有double参数并返回double值的方法 。 这由getIntegralValue方法处理。
  • getIntegralValue方法中将接口替换为函数指针作为参数后,应调用getIntegralValue ,就像它是函数指针一样:

      for(int i = integralCalc.getIntegralValue(a); i < integralCalc.getIntegralValue(b); i += dx) { ... }