430

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

16 に答える 16

290

ラムダは純粋に呼び出しサイトの構成要素です。ラムダの受信者は、ラムダが関与していることを知る必要はありません。代わりに、適切なメソッドでインターフェイスを受け入れます。

つまり、必要なものを正確に受け入れて返す機能的なインターフェイス (つまり、単一のメソッドを持つインターフェイス) を定義または使用します。

このため、Java 8 には一般的に使用されるインターフェイス タイプのセットが付属しています(JavaDoc に関するヒントを提供してくれたMaurice Naftalinjava.util.functionに感謝します)。

この特定のユースケースで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);
}

次に、ラムダをパラメータとしてメソッドを呼び出します。

public static void main(String[] args) {
    TwoArgIntOperator addTwoInts = (a, b) -> a + b;
    int result = method(addTwoInts);
    System.out.println("Result: " + result);
}

独自のインターフェースを使用すると、意図をより明確に示す名前を付けることができるという利点があります。

于 2012-11-28T12:09:03.720 に答える
72

Lambda 式を使用するには、独自の機能インターフェースを作成するか、2 つの整数を必要とし、値として返す操作に 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));

    }
}
于 2014-03-19T15:28:46.983 に答える
44

2 つ以上のパラメーターを持たない関数の場合、独自のインターフェイスを定義せずに渡すことができます。例えば、

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>>はその戻り値の型です。IntegerStringList<String>

パラメーターが 1 つしかない関数の場合、 を使用できますFunction<T, R>。ここで、Tはそのパラメーターの型であり、Rはその戻り値の型です。Java ですでに使用可能になっているすべてのインターフェースについては、 このページを参照してください。

于 2015-05-27T03:19:32.710 に答える
15

http://lambdafaq.org/lambda-resourcesからリンクされている、Lambda 対応の Java 8 JavaDocs の公開 Web アクセス可能なバージョンがあります。(これは明らかに Joachim Sauer の回答に対するコメントである必要がありますが、コメントを追加する必要がある評判ポイントで SO アカウントにアクセスできません。) lambdafaq サイト (私はそれを維持しています) がこれに回答し、他の多くの Java -ラムダの質問。

注: この回答は、Java 8 GA のドキュメントが公開される前に書かれたものです。ただし、Lambda FAQは、Java 8 で導入された機能について学ぶ人々にとって依然として役立つ可能性があるため、そのまま残しました。

于 2012-11-28T12:59:24.073 に答える
3

基本的に、ラムダ式をパラメーターとして渡すには、それを保持できる型が必要です。プリミティブintまたは Integer クラスで保持する整数値と同様です。Java には、ラムダ式の別の型がなく、代わりに引数を保持する型としてインターフェイスを使用します。しかし、そのインターフェースは機能的なインターフェースでなければなりません。

于 2019-05-10T07:32:25.067 に答える
-1

メソッドがインターフェイスによって実装されると、メソッドをパラメーターとして設定できます。

于 2021-10-14T15:54:14.680 に答える