13

「 clojure.lang.IFn」インターフェースに準拠する高階関数を生成する Clojure のライブラリーを多数使用しています。

複数のアリティ オーバーロードがあります。つまり、インターフェイスは次のようになります。

public interface IFn extends Callable, Runnable{
  public Object invoke() ;
  public Object invoke(Object arg1) ;
  public Object invoke(Object arg1, Object arg2) ;
  public Object invoke(Object arg1, Object arg2, Object arg3) ;
  .... etc.
  public Object applyTo(ISeq arglist) ;
}

このタイプのオブジェクトを Java 8 で呼び出し可能なラムダ関数として直接使用できますか?

4

2 に答える 2

7

このタイプのオブジェクトを呼び出し可能なラムダとして使用するとはどういう意味ですか?

非常に単純なケースでは、Java 8ラムダは、構文糖衣+特定のタイプのインターフェース、つまり関数型インターフェースの匿名クラスの型推論と考えることができます [1]

上で使用したインターフェースActionListenerには、メソッドが1つだけあります。RunnableやComparatorなど、多くの一般的なコールバックインターフェイスにはこのプロパティがあります。メソッドが1つしかないすべてのインターフェースに名前を付けます:機能インターフェース。

備考:ラムダは実際には単なる砂糖ではありません。内部的には、匿名クラスとは異なる方法で実装され、セマンティックの違いもいくつかあります。この問題の詳細については、ProgrammersExchangeでこの優れた回答を参照してください。ただし、これは、この質問と回答のコンテキストではそれほど重要ではありません。

何らかの機能インターフェイスの値が期待される場所(メソッド引数、ローカル変数、フィールド宣言など)では、このメソッドを実装する匿名クラスに似たエンティティ、つまりラムダ式を作成するための短い構文を使用できます。

Runnable r = () -> {
    System.out.println("Hi");
};
// Equivalent to
Runnable r = new Runnable() {
    public void run() {
        System.out.println("Hi");
    }
};

public interface Function<F, T> {
    T call(F arg);
}

Function<String, char[]> c = s -> ("<" + s + ">").toCharArray();
// Equivalent to
Function<String, char[]> c = new Function<>() {
    public char[] call(String s) {
        return ("<" + s + ">").toCharArray();
    }
};

したがって、あなたの質問は次の方法でしか解釈できませんIFn。Java8ラムダ構文を使用してタイプのオブジェクトを作成することは可能ですか?

答えはいいえだ。Lambda構文は、関数型インターフェースでのみ可能です。clojure.lang.IFnは単一のメソッドよりもはるかに多く含まれているため、機能的なインターフェイスではありません。そのため、次のようなことはできません。

IFn f = (String s) -> s.toLowerCase();
于 2013-01-22T08:57:05.457 に答える