Должны ли выражения Lamda быть внутри метода?Могут ли они существовать вне метода в качестве члена класса - PullRequest
0 голосов
/ 31 декабря 2018

Я пытаюсь увидеть разницу в передаче функций в качестве параметров между Scala и Java.Я переехал в Scala несколько лет назад, мало общаясь с Java.Могу ли я иметь лямбда-выражение вне метода, как показано ниже?Он компилируется и работает нормально, но есть ли что-то не так с ним.До сих пор все примеры, которые я видел, содержали Lamdas внутри метода.Приведенный ниже код является лишь примером, я знаю, что вы можете добиться того же с помощью интерфейса поставщика.

@FunctionalInterface
public interface IFunc {

    String printMessage();
}


public class JavaFunc {

    public String message() {

        return functionA(functionB);
    }

    IFunc functionB = () ->  "Hi, I am functionB from Java, I am passed to functionA as a parameter.";

    public String functionA(IFunc funcB) {
        return funcB.printMessage();
    }

}

Ответы [ 3 ]

0 голосов
/ 31 декабря 2018

Другими словами, лямбда-выражения также называются функциональными объектами, поэтому везде, где вы можете использовать обычные объекты, вы также можете использовать лямбды: вы можете определить их как атрибуты, вы можете передать их как параметры метода и т. Д..

public ExampleClass {
    //Initializing the consumer with our method reference (subset of lambdas)
    static Consumer<Integer> printer = System.out::println;

    public static void useLambda(Consumer<Integer> myIntegerPrinter, Integer value) {
         myIntegerPrinter.accept(value);
    }

    public static void main(String[] args) {
         // passing the lambda as parameter to useLambda
         useLambda(printer, 100);
    }
}
0 голосов
/ 31 декабря 2018

Помните, что лямбда коротка.Он просто используется для определений методов, особенно для функциональных интерфейсов.Практически везде, где вы можете использовать объект, где вы определяете некоторую функцию (с простой логикой), вы также можете легко использовать Lambda.Хорошим примером для использования будет ActionListener.

Без лямбды мы можем сказать:

ActionListener al = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getActionCommand());
    }
};

С помощью лямбды мы можем сократить это до простого выражения:

ActionListener al = e -> System.out.println(e.getActionCommand());

Понятно, что они напрямую связаны друг с другом;«ActionEvent e» из оригинала просто объявляется как «e» во вторичном, так как компилятор уже знает, к какому типу он относится, и аналогичным образом мы можем определить тело метода, объявив, что он делает в единственной строке,

Теперь они также могут быть переданы в качестве параметров, потому что они, как и любой другой объект.Например, допустим, у нас был объект JButton, которому часто присваивается ActionListener.Обратите внимание, что JButton имеет метод JButton # addActionListener (ActionListener al).Теперь мы можем передать наш ActionListener любым из следующих способов:

JButton b = new JButton();
//Option One
ActionListener al = e -> System.out.println(e.getActionCommand());
b.addActionListener(al);
//Option Two
b.addActionListener(e -> System.out.println(e.getActionCommand()));
//Option Three
b.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getActionCommand());
    }
});
//Option Four
ActionListener al = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getActionCommand());
    }
};
b.addActionListener(al);

Все они логически эквивалентны!

0 голосов
/ 31 декабря 2018

Вы можете объявить лямбда-выражение в любом месте в классе

Если вы объявите внутри метода (который похож на локальные переменные, область действия внутри метода)

public String message() {

  IFunc functionB = () ->  "Hi, I am functionB from Java, I am passed to functionA as a parameter.";

    return functionA(functionB);
}

Если вы объявляете в классе (что аналогично переменным экземпляра, к которым можно обращаться во всех методах экземпляра напрямую и со ссылкой на объект в статической области)

public class JavaFunc {

 IFunc functionB = () ->  "Hi, I am functionB from Java, I am passed to functionA as a parameter.";

public String message() {

    // use here functionB
    return functionA(functionB);
}

Пример: лямбда-выражение для Predicate и анонимный внутренний класс

p1, p2 находятся на уровне экземпляра, а p3, p4 локальные

public class DemoMain {

Predicate<Integer> p1 = i -> i > 5;

Predicate<Integer> p2 = new Predicate<Integer>() {

    @Override
    public boolean test(Integer t) {
        // TODO Auto-generated method stub
        return false;
    }
};

public static void main(String args[]) {

    DemoMain m = new DemoMain();
    System.out.println(m.p1.test(10));
    System.out.println(m.p2.test(10));
}

public void m1() {

    System.out.println(p1.test(10));
    System.out.println(p2.test(10));

    Predicate<Integer> p3 = i -> i > 5;

    Predicate<Integer> p4 = new Predicate<Integer>() {

        @Override
        public boolean test(Integer t) {
            // TODO Auto-generated method stub
            return false;
            }
        };

    }

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