Как определить метод, который принимает лямбду в качестве параметра в Java 8?

В Java 8 методы могут быть созданы как лямбда-выражения и могут передаваться по ссылке (с небольшой работой под капотом). В Интернете можно найти множество примеров создания и использования лямбд с методами, но нет примеров того, как сделать метод, принимающий лямбду в качестве параметра. Каков синтаксис для этого?

MyClass.method((a, b) -> a+b);

class MyClass{
  //How do I define this method?
  static int method(Lambda l){
    return l(5, 10);
  }
}
Комментарии к вопросу (1)
Решение

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

Другими словами, вы определяете или используете функциональный интерфейс (т.е. интерфейс с одним методом), который принимает и возвращает именно то, что вы хотите.

Для этого Java 8 поставляется с набором часто используемых типов интерфейсов в java.util.function (спасибо Maurice Naftalin за подсказку о JavaDoc).

Для этого конкретного случая использования есть java.util.function.IntBinaryOperator с единственным методом int applyAsInt(int left, int right), так что вы можете написать свой метод следующим образом:

static int method(IntBinaryOperator op){
    return op.applyAsInt(5, 10);
}

Но вы также можете определить свой собственный интерфейс и использовать его следующим образом:

public interface TwoArgIntOperator {
    public int op(int a, int b);
}

//elsewhere:
static int method(TwoArgIntOperator operator) {
    return operator.op(5, 10);
}

Использование собственного интерфейса имеет то преимущество, что вы можете иметь имена, которые более четко указывают на намерение.

Комментарии (7)

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

Использование функционального интерфейса, определенного пользователем

interface TwoArgInterface {

    public int operation(int a, int b);
}

public class MyClass {

    public static void main(String javalatte[]) {
        // this is lambda expression
        TwoArgInterface plusOperation = (a, b) -> a + b;
        System.out.println("Sum of 10,34 : " + plusOperation.operation(10, 34));

    }
}

Использование функционального интерфейса Java

import java.util.function.IntBinaryOperator;

public class MyClass1 {

    static void main(String javalatte[]) {
        // this is lambda expression
        IntBinaryOperator plusOperation = (a, b) -> a + b;
        System.out.println("Sum of 10,34 : " + plusOperation.applyAsInt(10, 34));

    }
}

Другой пример, который я создал, находится здесь.

Комментарии (3)

Для функций, которые не имеют более 2-х параметров, вы можете пройти их без определения собственного интерфейса. Например,

class Klass {
  static List foo(Integer a, String b) { ... }
}

class MyClass{

  static List method(BiFunction fn){
    return fn.apply(5, "FooBar");
  }
}

List lStr = MyClass.method((a, b) -> Klass.foo((Integer) a, (String) b));

В BiFunction<целое число, строка, список<строка>>, целое и строка являются его параметры, и список<строка> у` - ее возвращаемый тип.

Для функции с одним параметром, вы можете использовать функция<Т, R>, где Т - это параметр типа, и Р является его тип возвращаемого значения. Обратитесь к этой страничке [] (https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html) для всех интерфейсов, которые уже доступны в Java.

Комментарии (0)

Существует общедоступная веб-версия Java 8 JavaDocs с поддержкой Lambda, ссылка на которую находится по адресу http://lambdafaq.org/lambda-resources. (Очевидно, это должен быть комментарий к ответу Joachim Sauer', но я не могу войти в свой аккаунт на SO с очками репутации, необходимыми для добавления комментария). Сайт lambdafaq (я его поддерживаю) отвечает на этот и многие другие вопросы по Java-lambda.

NB Этот ответ был написан до того, как документация по Java 8 GA стала общедоступной. Однако я оставил его на месте, поскольку Lambda FAQ все еще может быть полезен людям, изучающим возможности, появившиеся в Java 8.

Комментарии (4)

Для тех, кто погуглил этого, хорошим методом будет использование Ява.утиль.функция.BiConsumer. экс:

Import java.util.function.Consumer
public Class Main {
    public static void runLambda(BiConsumer lambda) {
        lambda.accept(102, 54)
    }

    public static void main(String[] args) {
        runLambda((int1, int2) -> System.out.println(int1 + " + " + int2 + " = " + (int1 + int2)));
    }

В outprint будет: 166

Комментарии (2)

Для меня, решение, которое наиболее логично определить интерфейс обратного вызова :

interface Callback {
    void call();
}

и затем использовать его в качестве параметра в функции вы хотите позвонить :

void somewhereInYourCode() {
    method(() -> {
        // You've passed a lambda!
        // method() is done, do whatever you want here.
    });
}

void method(Callback callback) {
    // Do what you have to do
    // ...

    // Don't forget to notify the caller once you're done
    callback.call();
}

Просто в точности, хотя

Лямбда-это не специальный интерфейс, класс или что-нибудь еще вы могли бы заявить о себе. "Лямбда" - это просто название, данное () -> {} специальный синтаксис, который позволяет лучше читаемость при прохождении одного метода интерфейса в качестве параметра. Она была разработана, чтобы заменить это :

method(new Callback() {
    @Override
    public void call() {
        // Classic interface implementation, lot of useless boilerplate code.
        // method() is done, do whatever you want here.
    }
});

Так в приведенном выше примере обратного вызова это не лямбда, это's просто обычный интерфейс ; лямбда - имя синтаксис ярлыка можно использовать для его реализации.

Комментарии (0)

Лямбда-выражение может быть передан в качестве аргумента.Чтобы передать лямбда-выражение в качестве аргумента тип параметра (который принимает лямбда-выражение в качестве аргумента) должен быть функциональный тип интерфейса.

Если есть функциональный интерфейс -

interface IMyFunc {
   boolean test(int num);
}

И есть метод filter, который добавляет инт в списке, только если она превышает 5. Здесь следует отметить, что метод фильтрации имеет funtional IMyFunc интерфейс в качестве одного из параметров. В этом случае лямбда-выражение может быть передана в качестве аргумента для параметра метод.

public class LambdaDemo {
    public static List filter(IMyFunc testNum, List listItems) {
        List result = new ArrayList();
        for(Integer item: listItems) {
            if(testNum.test(item)) {
                result.add(item);
            }
        }
        return result;
    }
    public static void main(String[] args) {
        List myList = new ArrayList();
        myList.add(1);
        myList.add(4);
        myList.add(6);
        myList.add(7);
        // calling filter method with a lambda expression
        // as one of the param
        Collection values = filter(n -> n > 5, myList);

        System.out.println("Filtered values " + values);
    }
}
Комментарии (0)

Вы можете использовать функциональные интерфейсы, как упоминалось выше. ниже приведены некоторые примеры

Function f1 = num->(num*2+1);
System.out.println(f1.apply(10));

Predicate f2= num->(num > 10);
System.out.println(f2.test(10));
System.out.println(f2.test(11));

Supplier f3= ()-> 100;
System.out.println(f3.get());

Надеюсь, что это помогает

Комментарии (0)

Хорошо, что's легко. Цель лямбда-выражение является реализация функционального интерфейса. Это интерфейс с одним методом. Здесь каждый статьи о стандартных и устаревших функциональных интерфейсов.

В любом случае, если вы хотите реализовать свой собственный функциональный интерфейс, сделать его. Просто на простом примере:

public interface MyFunctionalInterface {
    String makeIt(String s);
}

Так давайте's сделать класс, где мы создадим метод, который принимает тип MyFunctionalInterface :

public class Main {

    static void printIt(String s, MyFunctionalInterface f) {
        System.out.println(f.makeIt(s));
    }

    public static void main(String[] args) {

    }
}

Последняя вещь, которую вы должны сделать, это пройти осуществлении MyFunctionalInterface метод мы'вэ определено:

public class Main {

    static void printIt(String s, MyFunctionalInterface f) {
        System.out.println(f.makeIt(s));
    }

    public static void main(String[] args) {
        printIt("Java", s -> s + " is Awesome");
    }
}

Что's это!

Комментарии (0)

Лямда-это не объект, но функциональный интерфейс. Можно определить как функциональные интерфейсы, как они могут с помощью @FuntionalInterface в качестве аннотации

@FuntionalInterface
public interface SumLambdaExpression {
     public int do(int a, int b);
}

public class MyClass {
     public static void main(String [] args) {
          SumLambdaExpression s = (a,b)->a+b;
          lambdaArgFunction(s);
     }

     public static void lambdaArgFunction(SumLambdaExpression s) {
          System.out.println("Output : "+s.do(2,5));
     }
}

Вывод будет следующим образом

Output : 7

Основная концепция лямбда-выражения, чтобы определить собственную логику, но уже определенными аргументами. Так в приведенном выше коде вы можете изменить описание функции дополнение к любому другому определению, но ваши аргументы ограничиваются 2.

Комментарии (0)

В основном, чтобы пройти лямбда выражения в качестве параметра, нам нужен тип, в котором мы можем его удержать. Просто как целочисленное значение, мы держим в первобытном инт или целого класса. Ява не'т иметь отдельный вид для выражения лямбда вместо этого он использует интерфейс как тип, чтобы держать аргумент. Но, что интерфейс должен быть функциональный интерфейс.

Комментарии (0)

Выполните следующие действия ..

Вы объявили метод(лямда-л)` Все, что вы хотите сделать, это создать интерфейс с именем "лямбда" и объявить один абстрактный метод

public int add(int a,int b);  

имя метода не имеет значения здесь..

Поэтому, когда ты называешь класса MyClass.способ( (А,B)->а+B) Эта реализация (а,б)->а+B будет введен в ваш интерфейс метод Add .Поэтому, когда вы называете я.добавитьэто собирается занять эту реализацию и выполнять сложениеAиBивозвращение л.добавить(2,3)вернет5`.

  • В основном это то, что лямбда делает..
Комментарии (0)

Существует гибкость в использовании лямбда-выражение в качестве параметра. Это дает возможность функционального программирования в Java. Базовый синтаксис

парам -> method_body

Ниже приведен способ, можно определить способ принятия функциональный интерфейс (используется лямбда) в качестве параметра. а. если вы хотите определить метод, объявленный внутри функциональный интерфейс, скажем, функциональный интерфейс приведен как аргумент/параметр в метод вызывается из основной()`

@FunctionalInterface
interface FInterface{
    int callMeLambda(String temp);
}

class ConcreteClass{

    void funcUsesAnonymousOrLambda(FInterface fi){
        System.out.println("===Executing method arg instantiated with Lambda==="));
    }

    public static void main(){
        // calls a method having FInterface as an argument.
        funcUsesAnonymousOrLambda(new FInterface() {

            int callMeLambda(String temp){ //define callMeLambda(){} here..
                return 0;
            }
        }
    }

/***********Can be replaced by Lambda below*********/
        funcUsesAnonymousOrLambda( (x) -> {
            return 0; //(1)
        }

    }

FInterface интернет = (х) -> { вернуть 0; };

funcUsesAnonymousOrLambda(пэз);

здесь выше видно, как лямбда-выражение может быть заменен интерфейс.

Выше объясняет особенности использования лямбда-выражения, есть более. Реф https://stackoverflow.com/questions/23451579/java-8-lambda-within-a-lambda-cant-modify-variable-from-outer-lambda

Комментарии (0)