【问题标题】:Map of String to Method in Java 8, passing parametersJava 8中字符串到方法的映射,传递参数
【发布时间】:2015-03-04 03:26:21
【问题描述】:

好的,我一直在努力寻找这个问题的答案,但我无法理解新的 java 8 lambda 和方法引用。

我正在编写一个 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 中的 lambdas 和 Method references,但我就是想不通。无论如何,我的最终想法是为每个内核创建一个字符串映射(内核名称)到方法。然后将整个分类方法简化为:

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 循环,但首先我想了解 lambda 和方法引用。

【问题讨论】:

  • 我认为你不需要 lambdas。您可以使用多态性或简单的switch

标签: java dictionary methods lambda java-8


【解决方案1】:

定义一个地图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

【讨论】:

  • 谢谢!现在这有点道理。
【解决方案2】:

不要为了使用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 的switch 语句。

【讨论】:

    猜你喜欢
    • 2011-11-21
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 2011-10-06
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多