Java实现辛普森1/3数值积分时如何支持传入任意自定义被积函数
实现自定义被积函数的辛普森1/3积分修改方案
核心修改逻辑
利用Java的函数式接口将被积函数抽象为参数传入,替代原有的硬编码对数函数,同时修复原代码中数组长度固定导致的越界问题。
1 改造Simpsons13积分类
package appMatematica; import java.util.function.Function; public class Simpsons13 { // 新增Function参数接收自定义被积函数 static float simpsons13(float ll, float ul, int n, Function<Float, Float> function) { float h = (ul - ll) / n; // 数组长度改为动态n+1,修复原代码n>9时的数组越界bug float[] x = new float[n + 1]; float[] fx= new float[n + 1]; for (int i = 0; i <= n; i++) { x[i] = ll + i * h; // 调用传入的函数计算f(x) fx[i] = function.apply(x[i]); } float res = 0; for (int i = 0; i <= n; i++) { if (i == 0 || i == n) res += fx[i]; else if (i % 2 != 0) res += 4 * fx[i]; else res += 2 * fx[i]; } res = res * (h / 3); return res; } }
改动说明
- 移除硬编码的对数函数
func方法,新增Function<Float, Float>类型入参 - 存储x和f(x)的数组长度改为动态的
n+1,避免分段数大于9时报数组越界错误 - 函数值计算逻辑改为调用传入的Function实例的
apply方法
2 调整主类调用代码
只需要修改辛普森1/3积分对应的调用分支,通过lambda表达式传入自定义被积函数即可:
if (op == 3) { float limite_inferior; float limite_superior; int i; System.out.println("Digite o limite inferior\n"); limite_inferior = sc.nextFloat(); System.out.println("Digite o limite superior\n"); limite_superior = sc.nextFloat(); System.out.println("Digite o número de iterações\n"); i = sc.nextInt(); // 示例1:传入原有的对数函数 float result = Simpsons13.simpsons13(limite_inferior, limite_superior, i, x -> (float)Math.log(x)); // 示例2:如果要计算f(x)=x²的积分,替换为如下写法即可 // float result = Simpsons13.simpsons13(limite_inferior, limite_superior, i, x -> x * x); System.out.println(result); }
低版本Java兼容方案
如果使用的是Java 8之前不支持函数式接口的版本,可以自定义一个函数接口替代:
// 自定义函数接口 public interface MathFunction { float compute(float x); }
将Simpsons13类的入参改为MathFunction function,调用时改为function.compute(x[i]),传参时用匿名内部类即可:
float result = Simpsons13.simpsons13(limite_inferior, limite_superior, i, new MathFunction() { @Override public float compute(float x) { return (float) Math.log(x); } });
内容的提问来源于stack exchange,提问作者Gustavo Goulart
相关产品推荐
相关产品推荐

