使用lambda执行void:这是正确的吗?

时间:2014-02-02 13:10:21

标签: java lambda java-8

我正在做的是正确的吗?我基本上想要执行某种void方法。

public abstract class Uniforms {
    public static void setUniformMatrix4(final UniformLocation uniformLocation, final boolean transpose, final Matrix4f matrix4f) {
        setUniformImpl(uniformLocation, u -> GL20.glUniformMatrix4(uniformLocation.getLocation(), transpose, matrix4f.asFloatBuffer()));
    }

    public static void setUniformMatrix4(final UniformLocation uniformLocation, final boolean transpose, final FloatBuffer matrix4fFloatBuffer) {
        setUniformImpl(uniformLocation, u -> GL20.glUniformMatrix4(uniformLocation.getLocation(), transpose, matrix4fFloatBuffer));
    }

    public static void setUniform(final UniformLocation uniformLocation, final float value) {
        setUniformImpl(uniformLocation, u -> GL20.glUniform1f(uniformLocation.getLocation(), value));
    }

    public static void setUniform(final UniformLocation uniformLocation, final int value) {
        setUniformImpl(uniformLocation, u -> GL20.glUniform1i(uniformLocation.getLocation(), value));
    }

    private static void setUniformImpl(final UniformLocation uniformLocation, final Consumer<UniformLocation> consumer) {
        Program oldProgram = Program.getUsing();
        for (Program program : Program.getPrograms()) {
            if (program.usesUniform(uniformLocation)) {
                program.use();
                consumer.accept(uniformLocation);
            }
        }
        if (oldProgram != null) {
            oldProgram.use();
        }        
    }
}

2 个答案:

答案 0 :(得分:2)

如果它编译则没有问题。

假设方法需要:

void m(Consumer<SomeEvent> e);

然后在Java 7中你可以写:

m(new Consumer<SomeEvent> () { void accept(SomeEvent e) { /* do nothing */ } });

您提供的消费者忽略参数e

同样,使用lambdas,您可以忽略参数并写:

m(e -> { /* do nothing */ });

答案 1 :(得分:2)

如果您的程序编译并提供您期望的输出,那么从这个意义上说它是正确的。可以稍微澄清一下。

四个公共重载都采用UniformLocation参数,然后传递给setUniformImpl方法。然后,此方法调用使用者并将uniformLocation ...传递给它,然后将其忽略。 lambda中对GL2.glUniform*方法的调用全部捕获 uniformLocation,而不是使用u参数。您可以将Consumer替换为Runnable

或者,您可以将Consumer的类型更改为Uniform.getLocation()的返回值,并将每个调用提取到setUniformImpl并将结果作为arg传递给consumer.accept。这会简化一些事情。你最终会得到类似的东西,

public static void setUniform(final UniformLocation uniformLocation, final int value) {
    setUniformImpl(uniformLocation, u -> GL20.glUniform1i(u, value));
}

private static void setUniformImpl(final UniformLocation uniformLocation, final Consumer<Location> consumer) {
    ...
    consumer.accept(uniformLocation.getLocation());
    ...
}