模拟函数指针
以下类包含一个应使用回调技术计算积分的方法。
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) { ... }