具有非最终函数参数的Java Lambda表达式

时间:2016-10-09 05:25:50

标签: java lambda final

我试图通过使用Runnable接口简单地计算一个函数来包装我需要的任何函数。

private static double time(Runnable runnable) { // returns how long runnable took
    long startTime = System.nanoTime();
    runnable.run();
    return (System.nanoTime() - startTime) / 1000000000.0;
}

然后我可以简单地执行以下操作:

double durationOfFunctionA = time(Driver::functionA); // functionA belongs in class Driver

但是,如果我有一个带参数的函数,它必须修改为:

double durationOfFunctionB = time(() -> functionB(someParameter));

我遇到的问题是' someParameter'必须是最终的或有效的最终决定这个问题有解决方法吗?我看过使用forEach的循环,但是我需要这个参数从1,10,100开始指数 - >直到满足条件。代码是这样的:

public static void main(String[] args) {
    double timer = 0;
    int size = 1;

    while(timer <= 10) {
        timer = time(() -> functionB(size));
        size *= 10;
    }
}

我要求functionB接受一个参数,因为我想测试它的复杂性/大O。我担心我没有正确编码/使用lambda表达式。如果有人可以帮助解决这个问题或找到另一个解决方案,那将不胜感激。

作为旁注,我知道我不必使用Runnable接口使其如此复杂,我可以直接在while循环中进行计时。但是,我只是想看看是否可以做这样的事情,所以我可以输入一些函数进行测试,并作为语法糖。

2 个答案:

答案 0 :(得分:2)

您可以简单地将变量值复制到单独的最终变量中,如下所示:

double timer = 0;
int size = 0;
while(true) {
  final finalSize = size;
  timer = time(() -> functionB(finalSize));
  size *= 10;
}

另外,我可以建议你为你想要的时间函数的各种参数做一些更多的计时功能。 在这里你可以这样做:

public class Test {

    public static void main(final String[] args) {
        int ttt = 0;
        time(ttt, Test::func);
        time(ttt, ttt, Test::func);
    }

    public static void func(int i) {

    }

    public static void func(int i, int j) {

    }

    public static <T> double time(T arg, Consumer<T> func) {
        long startTime = System.nanoTime();
        func.accept(arg);
        return (System.nanoTime() - startTime) / 1000000000.0;
    }

    public static <T1, T2> double time(T1 arg1, T2 arg2, BiConsumer<T1, T2> func) {
        long startTime = System.nanoTime();
        func.accept(arg1, arg2);
        return (System.nanoTime() - startTime) / 1000000000.0;
    }

}

答案 1 :(得分:1)

试试这个。

public static void main(String[] args) {
    double timer = 0;
    final int[] size = {1};

    while(timer <= 10) {
        timer = time(() -> functionB(size[0]));
        size[0] *= 10;
    }
}

Lambda表达式通过在内部复制它们来引用自由变量。 因此,不得更改自由变量(必须为final)。 但是当你传递size[0]时,lambda表达式会复制数组变量size。 它是final