Java 8에서 람다를 매개 변수로 사용하는 메소드를 어떻게 정의합니까? 작성하는 방법에 대한 예제는

Java 8에서 메소드는 Lambda 표현식으로 작성 될 수 있으며 참조로 전달 될 수 있습니다 (후드에서 약간의 작업만으로). 람다는 작성되고 메소드와 함께 사용되는 많은 예제가 온라인에서 있지만 람다를 매개 변수로 사용하는 메소드를 작성하는 방법에 대한 예제는 없습니다. 그 구문은 무엇입니까?

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


class MyClass{
  //How do I define this method?
  static int method(Lambda l){
    return l(5, 10);
  }
}



답변

람다는 순전히 호출 사이트 구조입니다. 람다의 수신자는 람다가 관련된 것을 알 필요가 없으며 대신 적절한 방법으로 인터페이스를 허용합니다.

다시 말해, 원하는 것을 정확하게 수용하고 반환하는 기능적 인터페이스 (예 : 단일 메소드가있는 인터페이스)를 정의하거나 사용합니다.

이 Java 8에는 일반적으로 사용되는 인터페이스 유형 세트가 포함되어 있습니다 java.util.function( JavaDoc에 대한 힌트는 Maurice Naftalin 덕분입니다 ).

이 특정 사용 사례를 들어 거기 java.util.function.IntBinaryOperator하나의 int applyAsInt(int left, int right)방법 당신은 당신을 쓸 수 있도록 method다음과 같이 :

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);
}

자체 인터페이스를 사용하면 의도를보다 명확하게 나타내는 이름을 가질 수 있다는 이점이 있습니다.


답변

Lambda 표현식을 사용하려면 고유 한 기능 인터페이스를 작성하거나 두 개의 정수가 필요하고 값으로 리턴되는 조작에 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));

    }
}

내가 만든 다른 예는 여기


답변

두 개 이상의 매개 변수가없는 함수의 경우 고유 한 인터페이스를 정의하지 않고 전달할 수 있습니다. 예를 들어

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

class MyClass{

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

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

에서가 BiFunction<Integer, String, List<String>>, Integer그리고 String매개 변수, 그리고 List<String>그것의 반환 유형입니다.

하나 개의 매개 변수와 함수, 당신은 사용할 수 있습니다를 들어 Function<T, R>, 경우 T의 매개 변수 유형이며, R반환 값 타입이다. Java에서 이미 사용 가능한 모든 인터페이스는 이 페이지 를 참조하십시오 .


답변

http://lambdafaq.org/lambda-resources 에서 링크 된 공개 웹 액세스 버전의 Lambda 지원 Java 8 JavaDoc이 있습니다. 있습니다. (이것은 분명히 Joachim Sauer의 답변에 대한 의견이어야하지만 의견을 추가 해야하는 평판 포인트로 내 SO 계정에 들어갈 수는 없습니다.) lambdafaq 사이트 (유지)는 이것과 다른 많은 Java에 대답합니다. 람다 질문.

NB이 답변은 Java 8 GA 문서가 공개 되기 전에 작성되었습니다 . 그래도 Lambda FAQ 는 Java 8에 도입 된 기능에 대해 배우는 사람들에게 유용 할 수 있기 때문에 그대로 두었습니다 .


답변

나에게 가장 의미있는 해결책은 Callback인터페이스 를 정의하는 것입니다 .

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();
}

그래도 정밀함

람다는 특별한 인터페이스, 클래스 또는 직접 선언 할 수있는 것이 아닙니다. Lambda() -> {}단일 구문 인터페이스를 매개 변수로 전달할 때 가독성을 향상 시키는 특수 구문에 지정된 이름 입니다. 이것을 대체하도록 설계되었습니다.

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

위의 예 에서 람다 Callback아니며 일반적인 인터페이스 일뿐입니다. lambda구현하는 데 사용할 수있는 바로 가기 구문의 이름입니다.


답변

인터넷 검색을하는 사람에게는을 사용하는 것이 좋습니다 java.util.function.BiConsumer. 전의:

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

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

결과는 다음과 같습니다. 166


답변

람다 식을 인수로 전달할 수 있습니다. 람다 식을 인수로 전달하려면 람다 식을 인수로받는 매개 변수의 유형이 기능적인 인터페이스 유형이어야합니다.

기능적인 인터페이스가있는 경우-

interface IMyFunc {
   boolean test(int num);
}

그리고 int가 5보다 큰 경우에만 int를 목록에 추가하는 필터 메소드가 있습니다. 여기서 필터 메소드에는 매개 변수 중 하나로 IMyFunc 인터페이스가 있습니다. 이 경우 람다 식을 메서드 매개 변수의 인수로 전달할 수 있습니다.

public class LambdaDemo {
    public static List<Integer> filter(IMyFunc testNum, List<Integer> listItems) {
        List<Integer> result = new ArrayList<Integer>();
        for(Integer item: listItems) {
            if(testNum.test(item)) {
                result.add(item);
            }
        }
        return result;
    }
    public static void main(String[] args) {
        List<Integer> myList = new ArrayList<Integer>();
        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<Integer> values = filter(n -> n > 5, myList);

        System.out.println("Filtered values " + values);
    }
}