ホームページ  >  に質問  >  本文

java - これは匿名の内部クラスにありますが、ラムダで取得するにはどうすればよいですか?

リーリー

上記のコードがラムダに変換されると、これは外部クラスを指すことになり、現時点ではリスナーを削除できません。
そこでお聞きしたいのですが、匿名内部クラス (ラムダに変換できる匿名内部クラス) はどのようにしてラムダ内で自身を取得できるのでしょうか?

阿神阿神2675日前1062

全員に返信(2)返信します

  • PHP中文网

    PHP中文网2017-06-23 09:15:26

    一部の匿名内部クラスを置き換える
    このセクションでは、ラムダ式を使用して匿名内部クラスの作成を簡略化する方法を紹介します。ただし、ラムダ式は、 Functional Interface の略語を置き換えるためにのみ使用できます。詳細についてはまだ心配しないでください。いくつかの例を見てみましょう。

    例 1: パラメーターのない関数の略語
    新しいスレッドを作成する必要がある場合、一般的な書き方は次のようになります:

    // JDK7 匿名内部クラス記述メソッド
    new Thread(new Runnable(){// インターフェース名

    リーリー

    }).start();
    上記のコードは、匿名の Runnable オブジェクトを Tread クラスに渡し、Runnable インターフェイスの run() メソッドをオーバーロードして、対応するロジックを実装します。 JDK7以前では一般的な書き方です。匿名の内部クラスを使用すると、クラスに名前を付ける手間が省けますが、それでも十分単純ではありません。Java 8 では、次の形式に簡略化できます。

    // JDK8ラムダ式の書き方

    new Thread(
    リーリー

    ).start();

    上記のコードは匿名内部クラスと同じ機能を持ちますが、匿名内部クラスよりもさらに進化しています。ここでは、接続ポート名と関数名が一緒に省略されているため、よりすっきりと記述できます。関数本体に複数の行がある場合は、次のように中括弧で囲むことができます:

    // JDK8 ラムダ式コードブロックの書き方

    new Thread(
    リーリー

    ).start();

    例 2: パラメータを使用した関数の省略形
    カスタム コンパレータを文字列リストに渡し、文字列の長さに従って並べ替えたい場合、Java 7 の記述形式は次のとおりです:

    // JDK7 での匿名内部クラスの書き方

    List<String> list = Arrays.asList("I", "love", "you", "too");
    Collections.sort(list, new Comparator<String> ;() {//インターフェース名
    リーリー

    });

    上記のコードは、比較ロジックを実装するために、内部クラスを通じて Comparator インターフェイスの Compare() メソッドをオーバーロードします。ラムダ式の使用は次のように省略できます:

    // JDK8ラムダ式の書き方

    List<String> list = Arrays.asList("I", "love", "you", "too");
    Collections.sort(list, (s1, s2) - > ;{// パラメータテーブルの種類を省略します
    リーリー

    });

    上記のコードは、匿名内部クラスと同じ機能を持ちます。コードではインターフェイス名とメソッド名が省略されているだけでなく、パラメータ テーブルの型も省略されています。これは、javac の型推論メカニズムによるもので、コンパイラはコンテキスト情報に基づいてパラメータの型を推論できますが、推論が失敗する場合もあり、その場合はパラメータの型を手動で指定する必要があります。 Java は厳密に型指定された言語であり、各変数とオブジェクトには明確な型が必要であることに注意してください。

    略語の根拠

    おそらく、Lambda を使用するための基礎は、対応する関数型インターフェイスが存在する必要があるということだとすでに考えているでしょう (関数型インターフェイスとは、内部に抽象メソッドが 1 つだけあるインターフェイスを指します)。これは、Java が厳密に型指定された言語であることと一致しています。つまり、コード内の任意の場所にラムダ式を記述することはできません。実際には、Lambda の型は関数インターフェースに対応する型です。ラムダ式のもう 1 つの基礎は、型推論メカニズムです。コンテキスト情報が十分であれば、コンパイラーは明示的に名前を付けずにパラメーター テーブルの型を推論できます。 Lambda は、次のようにより合法的な書面形式を表現します:

    // Lambda 式の記述形式
    Runnable run = () -> System.out.println("Hello World");// 1
    ActionListener リスナー = events -> );// 2
    実行可能な multiLine = () -> 3 コード ブロック

    リーリー

    };
    BinaryOperator<Long> add = (Long x, Long y) -> x + y;// 4
    BinaryOperator<Long> 推論
    はパラメータなし関数の略称を示し、2はパラメータ化関数の略称と型推論機構を示し、4と5は再び型推論機構を示す。

    カスタム関数インターフェース
    カスタム関数インターフェースは簡単で、抽象メソッドを 1 つだけ持つインターフェースを記述するだけです。

    // カスタム関数インターフェイス
    @FunctionalInterface
    パブリック インターフェイス ConsumerInterface<T>{

    リーリー 上記のコードの

    }
    @FunctionalInterface はオプションですが、このアノテーションを追加すると、コンパイラはインターフェイスが関数インターフェイス仕様に準拠しているかどうかを確認するのに役立ちます。 @Override アノテーションを追加すると、関数がオーバーロードされているかどうかがチェックされるのと同様です。

    上記のインターフェイス定義を使用すると、次のようなコードを作成できます:

    ConsumerInterfaceconsumer = str -> System.out.println(str);

    さらに、次のように使用することもできます:

    クラス MyStream<T>{

    リーリー

    }
    MyStream<String> stream = new MyStream<String>();
    stream.myForEach(str -> System.out.println(str));// カスタム関数インターフェイスを使用してラムダ式を作成します

    返事
    0
  • 女神的闺蜜爱上我

    女神的闺蜜爱上我2017-06-23 09:15:26

    Lambda 自体がオブジェクトではないということはできません。

    返事
    0
  • キャンセル返事