以下类包含一个应使用回调技术计算积分的方法。
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=(b-a)/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)
{
}
}
在这种情况下如何进行回调?由于它的复杂性和丑陋性,我宁愿避免使用☞such solution☜。即使它是最不痛苦的,我也不知道如何在这里实现它。
答案 0 :(得分:5)
在这种情况下如何进行回调?由于它的复杂性和丑陋性,我宁愿避免使用such solution。即使它是最不痛苦的,我也不知道如何在这里实现它。
由于Java中没有函数指针,因此您必须使用通用接口。然后,您的功能必须是该接口的实现。是否要为实现类(即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
答案 1 :(得分:2)
此答案适用于不支持闭包或回调的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=(b-a)/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);
}
});
}
}
从上面的代码:
double (*f)(double)
参数将无效,而是使用抽象类或接口。 IMO界面会更好。double (*f)(double)
表示一个方法,其double
作为参数并返回double
值。这由getIntegralValue
方法处理。在接口中将函数指针替换为TrapezoidalIntegration
方法中的参数后,应调用getIntegralValue
,就好像它是函数指针一样:
for(int i = integralCalc.getIntegralValue(a);
i < integralCalc.getIntegralValue(b); i += dx) { ... }