Java 8 лямбда (из javascript примера) - PullRequest
4 голосов
/ 06 марта 2020

Я изучаю java из javascript фона, и мне интересно, можно ли написать подобную функцию в Java. Вот пример в javascript:

function getBalance(side, date) {
    let balance;
    let getPrice = (f) => {
        while ((result = f(date)) == 0) {
            date++;
        }
        return result;
    }
    if (side) {
        let price = getPrice(getPrice1);
        // Some calculations
        return balance;
    } else {
        let price = getPrice(getPrice2);
        // Some calculations
        return balance;
    }
}

, где getPrice1 и getPrice2 - ранее определенные функции. Использование обратных вызовов помогает сохранить короткий код. Я не уверен, что в Java можно передать функцию в качестве аргумента, не объявляя дополнительные интерфейсы.

Я задал этот вопрос, потому что это упрощенный пример реальной задачи, с которой я столкнулся. Как вы думаете, что будет самым элегантным решением?

PS Похоже, функциональные интерфейсы - вот путь.

Ответы [ 2 ]

4 голосов
/ 06 марта 2020

Вот решение, которое выглядит довольно близко к коду javascript:

import java.time.LocalDate;

public class Showcase {
    public static void main(String[] args) {
        LocalDate date = LocalDate.now();

        double result1 = getPrice(priceFunction1, date);
        double result2 = getPrice(priceFunction2, date);
    }

    private static double getPrice(PriceFunction priceFunction, LocalDate date) {
        return priceFunction.getPrice(date);
    }

    private static final PriceFunction priceFunction1 = date -> date.getYear() * 0.5;
    private static final PriceFunction priceFunction2 = date -> date.getYear() * 1.5;

    @FunctionalInterface
    private interface PriceFunction {
        double getPrice(LocalDate date);
    }
}

Вместо использования стандартных функциональных интерфейсов из языка java, таких как Function, просто определите новый функционал интерфейс, который точно соответствует требованиям вашей функции: он принимает дату и возвращает двойное значение.

Функция getPrice принимает такую ​​«функцию» в качестве первого аргумента, затем мы должны передать дату (javascript области видимости там немного легче ...). Сами «функции» являются лямбда-выражениями, и мы можем хранить их как поля или константы c.

Пурист может кричать, что я не выбрал кричащий случай для имен, но я специально отклонился от общих соглашений об именах ради удобства чтения.

3 голосов
/ 06 марта 2020

Да, это возможно.

Вот фиктивная витрина, просто чтобы проиллюстрировать, как все можно собрать воедино.

class Showcase {

    public static void main(String[] args) {
        Function<Function<LocalDate, Double>, Double> getPrice = f -> {
            // an example how to call it - replace it with your logic
            f.apply(LocalDate.now());

            return 0.;
        };

        getPrice.apply(Showcase::getPrice1);
        getPrice.apply(Showcase::getPrice2);
    }

    public static Double getPrice1(LocalDate date) {
        return 0.;
    }

    public static Double getPrice2(LocalDate date) {
        return 1.;
    }

}

Это было бы более многословно из-за дисциплины набора текста. Однако идея в принципе та же самая.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...