java - 在 Java 中传递具有参数定义行为的函数

标签 java function lambda parameter-passing function-pointers

在 Java 中,我想定义一个规范化函数,它接受一个数字作为输入,但其行为由多个参数定义。

本质上,Java 中的 Lisp 等价物:

(define (normalizeVal min max floor ceiling)
  (lambda (x) (/ (* (- ceiling floor) (- x min)) (+ (- max min) floor))))

在伪代码中,我想:

function parsing(data, normalizeValFunc) {
   for (datum in data):
      normalizeValFunc(datum);
}

var input = userData;
var min, max, floor, ceiling = /* Calculate min, max, floor, and ceiling */
var output = parsing(input, normalizeValFunc(min, max, floor, ceiling));

在 Java 中将函数作为参数传递可能很棘手,因为函数不是 Java 中的第一类对象。 (也许 Java 8 Lambda 表达式会改变这一点?)其他问题解决了在 Java 中将函数作为参数传递的问题,例如 How to pass a function as a parameter in Java? , What's the nearest substitute for a function pointer in Java? ,和 Function Pointers in Java

但是,这些问题都不涉及传递其行为由函数输入值以外的参数定义的函数。我事先不知道归一化函数的 min、max、floor 和 upper 参数是什么,但我只希望有效的归一化函数采用一个参数,即要归一化的值。

最佳答案

老式的方法是使用接口(interface):

public interface Normalizer {
    int normalize(int value);
}

然后您将创建一个 Normalizer 的实例,例如使用匿名类:

public static Normalizer normalizeValFunc(final int min, final int max, final int floor, final int ceiling) {
    return new Normalizer() {
        @Override public int normalize(int value) {
            /* Use min, max, floor, ceiling & value here to return something. */
        }
    };
}

然后您可以编写一个采用Normalizer的函数:

void parsing(int[] data, Normalizer normalizer) {
  // Call normalizer.normalize(...)
}

并这样调用它:

parsing(/* something here */, normalizeValFunc(min, max, floor, ceiling))

在 Java 8 中,您可以避免使用匿名类,而只使用 lambda:

public static normalizeValFunc(final int min, final int max, final int floor, final int ceiling) {
    return value -> /* Use min, max, floor, ceiling & value here to return something. */
}

您也可以内联执行此操作:

parsing(/* something here */, value -> /* an expression using min, max, floor, ceiling, value */)

此外,您可以只使用标准 IntUnaryOperator,而不是定义 Normalizer函数式接口(interface)(并调用 applyAsInt 而不是 normalize)。

关于java - 在 Java 中传递具有参数定义行为的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24148175/

相关文章:

java - optaplanner-spring-boot-starter 与 kie-server-spring-boot-starter

python - 在Python2.7中如何使用主脚本和其他用户定义函数中的变量

Java 8 替代 Map.entry() 将值映射到新 Map?

java - jackson 无法使用最终字段反序列化最简单的对象

java - 扩展 Struts 框架的 FilterDispatcher 是一个好的实践吗?

c++ - 逻辑比较运算符

lambda - DrRacket : lambda anonymous function

c++ - 使用 ubuntu 终端在 c++ 上运行线程类的问题

java - Spring Boot - 如何从 file.conf 读取环境变量

r - 在 R 中引用参数