Java 8中String to Method的映射,传递参数

时间:2015-03-04 03:26:22

标签: java dictionary methods lambda java-8

好的,我一直试图找到答案,我无法绕过新的java 8 lambdas和Method引用。

我正在写一个SVM解码器。我有这个模型,由libSVM创建,可以获得所有相关信息,如内核类型和常量,如rho和gamma。我有一个函数,它接受一个向量并使用模型的内核类型对其进行分类。目前我只是使用一个开关来确定要使用的内核:

public double classify(FeatureVector v){
    double fx = 0.0;

    switch(kernel){
        case "linear":
            for(FeatureVector xi : supportVectors){
                fx += (xi.getWeight() * crossProduct(xi, v));
            }

            break;
        case "polynomial":
            for(FeatureVector xi : supportVectors){
                fx += (xi.getWeight() * polynomialKernel(xi, v));
            }

            break;
        case "rbf":
            for(FeatureVector xi : supportVectors){
                fx += (xi.getWeight() * rbfKernel(xi, v));
            }

            break;
        case "sigmoid":
            for(FeatureVector xi : supportVectors){
                fx += (xi.getWeight() * sigmoidKernel(xi, v));
            }

            break;
        default:
            break;
    }

    return fx - rho;
}

现在,这很好用。但它很丑陋而难以遵循。我一直在阅读8中的lambda和方法参考,我只是想不出来。无论如何,我的最终想法是为每个内核的方法创建一个字符串映射(内核名称)。然后将整个分类方法简化为以下内容:

public double classify(FeatureVector v){
    double fx = 0.0;
    //get the method from map, this is where I need the help

    for(FeatureVector xi : supportVectors){
        //and how do I then pass params to the method?
        fx += (xi.getWeight() * kernelMethod(xi, v));
    }
    return fx - rho;
}

还有一种方法可以使用流然后执行整个for-each循环,但首先我想了解lambdas和方法引用。

2 个答案:

答案 0 :(得分:3)

定义地图Map<String, BiFunction<FeatureVector, FeatureVector, Double>> functions,添加您的功能,例如functions.put("linear", ThisClass::crossProduct)然后再做

BiFunction<FeatureVector, FeatureVector, Double> function = functions.get(...); 
fx += xi.getWeight() * function.apply(xi, v);

如果是crossProduct和co。不是静止的,您需要改为this::crossProduct

答案 1 :(得分:1)

不要仅使用lambda来使用lambda ...

我会像这样简单地重构您的代码:

for(FeatureVector xi : supportVectors)
{
    switch(kernel){
        case "linear":
            fx += (xi.getWeight() * crossProduct(xi, v));
            break;
        case "polynomial":
            fx += (xi.getWeight() * polynomialKernel(xi, v));
            break;
        case "rbf":
            fx += (xi.getWeight() * rbfKernel(xi, v));
            break;
        case "sigmoid":
            fx += (xi.getWeight() * sigmoidKernel(xi, v));
            break; 
    }
}

您可能希望阅读有关polymorphism的内容,以避免此类切换语句随时间推移最有可能成为spaghetti code