Передать функцию с определенным параметром поведением в Java
В Java я хочу определить нормализующую функцию, которая принимает одно число в качестве входных данных, но поведение которых определяется несколькими параметрами.
По сути, Java-эквивалент этого в Лиспе:
(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 лямбда-выражений меняет это?) Другие вопросы касаются проблемы передачи функций в качестве параметров в Java, например, Как передать функцию в качестве параметра в Java? Что является ближайшей заменой указателю на функцию в Java? и указатели на функции в Java
Однако ни один из этих вопросов не касается передачи функции, поведение которой определяется параметрами, отличными от входного значения функции. Я не знаю заранее, какими будут параметры min, max, floor и потолка функции нормализации, но я только хочу, чтобы эффективная нормализующая функция принимала один аргумент, значение было нормализовано.
1 ответ
Старомодный способ сделать это с помощью интерфейса:
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 вы можете избежать анонимного класса и просто использовать лямбду:
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 */)
Кроме того, вместо определения Normalizer
Вы можете просто использовать стандарт IntUnaryOperator
функциональный интерфейс (и вызов applyAsInt
вместо normalize
).