Java 如何提取不在数据结构上的二进制搜索?

Java 如何提取不在数据结构上的二进制搜索?,java,search,numerical-methods,abstraction,Java,Search,Numerical Methods,Abstraction,我有一个Java程序,在其中我发现我已经手动实现了三次二进制搜索算法。问题是,这种搜索不是在填写好的数据结构上进行的;相反,它是通过调用数值方法来实现的,这在计算上非常昂贵(因此需要进行二进制搜索;我正试图减少调用此方法的次数)。方法头看起来像: double computeValue1 (Thing thing, int parameter, int seed) 此方法始终返回0和1之间的双精度值。函数是单调递增的(较高的种子值总是返回较高的输出;因此二进制搜索是合理的)。我正在使用搜索来查

我有一个Java程序,在其中我发现我已经手动实现了三次二进制搜索算法。问题是,这种搜索不是在填写好的数据结构上进行的;相反,它是通过调用数值方法来实现的,这在计算上非常昂贵(因此需要进行二进制搜索;我正试图减少调用此方法的次数)。方法头看起来像:

double computeValue1 (Thing thing, int parameter, int seed)
此方法始终返回0和1之间的双精度值。函数是单调递增的(较高的
种子值总是返回较高的输出;因此二进制搜索是合理的)。我正在使用搜索来查找
seed
的值,该值返回一个最接近0.5的值(给定固定的
对象
参数

因此,理想情况下,我可以使用Java中的一些抽象库方法来完成搜索,而不是在代码中写出详细信息。此外,我实际上对3种不同的评估方法进行了3次不同的搜索(比如,
computeValue1
computeValue2
,然后第三次,我在保持
Thing
seed
固定的情况下对
参数进行相同的搜索)


什么是提取二进制搜索的优雅方法,这样我就不会维护三种不同的搜索方法(三种计算方法各一种),它们基本上都在做相同的事情?

只要搜索参数的数据类型相同(
int
,在您的情况下),您就可以这样做:

public int binarySearch(double targetValue, int from, int to, Function<Integer, Integer> compute) {
    while (...) {
        int currentParameter = ...;
        int currentValue = compute.apply(currentParameter);
        ...
    }
}
如果没有Java 8,则需要自己定义
函数
接口:

public interface Function<TParameter, TResult> {
    TResult apply(TParameter parameter);
}
公共接口功能{
TResult apply(t参数参数);
}
并使用匿名内部类调用搜索:

int seed1 = binarySearch(0.42, 0, 1000, new Function<Integer, Integer>() {
    public Integer apply(Integer parameter) {
        return computeValue1(someThing, someParameter, parameter));
    }
});
int-seed1=binarySearch(0.42,0,1000,新函数(){
公共整数应用(整数参数){
返回computeValue1(someThing,sometParameter,parameter));
}
});

您可以再添加一些代码吗?如果您使用的是Java 8,也许您可以这样做:
双计算值(T thing,int参数,int种子,Function expensiveFunction)
太好了,我不知道在Java 8中现在可以将方法作为参数传递。谢谢你的消息!(另外,自我声明的函数类比我想到的更优雅,好东西。)谢谢!(尽管Java8One更好,因为它使用协方差和逆变,为方法参数的签名提供了更大的灵活性。)但是,请注意,在这个示例中,我没有传递方法,我传递的是a,它(与流一起)是Java8最棒(也是早就应该传递的)特性。您也可以传递方法:
binarySearch(0.42,0,1000,this::myMethod)
,但是该方法的签名必须与
函数
参数类型匹配。我只是第一次在Java中学习lambda表达式,我希望我能给出大约100票。好体贴!
int seed1 = binarySearch(0.42, 0, 1000, new Function<Integer, Integer>() {
    public Integer apply(Integer parameter) {
        return computeValue1(someThing, someParameter, parameter));
    }
});