ラムダ式ラムダ式 (クロージャとも呼ばれる) は、Java 8 のリリースを推進した最も重要な新機能です。 1. 需要分析新しいスレッドを作成し、スレッドで実行するタスクを指定します パブリック静的voidメイン(String[] args) { // 新しいスレッドを開始します new Thread(new Runnable() { @オーバーライド パブリックボイド実行() { System.out.println("新しいスレッドで実行されたコード: "+Thread.currentThread().getName()); } })。始める(); System.out.println("メインスレッドのコード: " + Thread.currentThread().getName()); } コード分析:
2. 初心者のためのラムダ式ラムダ式は匿名関数であり、渡すことができるコードとして理解できます。 new Thread(() -> { System.out.println("新しいスレッド ラムダ式..." +Thread.currentThread().getName()); }) 匿名内部クラスの構文は冗長です。ラムダ式を体験した後、ラムダ式は匿名内部クラスを簡素化する方法であることがわかりました。 3. ラムダ構文ルールLambda はオブジェクト指向のルールと規制を排除します。Lambda の標準形式は 3 つの部分で構成されます。
フォーマットの説明:
3.1 ラムダ演習1パラメータと戻り値のないLambdaを練習する インターフェースの定義 パブリックインターフェースUserService{ void 表示(); } 次に、メインメソッドを作成します。 パブリッククラスDemo03Lambda { パブリック静的voidメイン(String[] args) { goShow(新しいUserService() { @オーバーライド パブリックボイドショー(){ System.out.println("実行されたメソッドを表示..."); } }); System.out.println("-----------"); goShow(() -> { System.out.println("Lambda show メソッドが実行されました..."); }); } パブリック静的void goShow(UserService userService){ ユーザーサービスを表示します。 } } 出力:
3.2 ラムダ演習2パラメータと戻り値を使用してラムダ式のケースを完了する Personオブジェクトの作成 @データ @AllArgsコンストラクタ @NoArgsコンストラクタ パブリッククラスPerson { プライベート文字列名; プライベート整数の年齢。 プライベート整数の高さ; } 次に、複数の Person オブジェクトを List コレクションに保存し、これらのオブジェクトを年齢順に並べ替えます。 パブリック静的voidメイン(String[] args) { リスト<Person> リスト = 新しい ArrayList<>(); list.add(new Person("ジェイ・チョウ",33,175)); list.add(new Person("アンディ・ラウ",43,185)); list.add(new Person("周星驰",38,177)); list.add(new Person("郭富城",23,170)); Collections.sort(リスト、新しいComparator<Person>() { @オーバーライド パブリック int 比較(Person o1、Person o2) { o1.getAge()-o2.getAge() を返します。 } }); for (人 人 : リスト) { System.out.println(人); } } sortメソッドの2番目のパラメータはComparatorインターフェースの匿名内部クラスであり、実行されるメソッドにはパラメータと戻り値があるため、Lambda式として書き直すことができることがわかった。 パブリック静的voidメイン(String[] args) { リスト<Person> リスト = 新しい ArrayList<>(); list.add(new Person("ジェイ・チョウ",33,175)); list.add(new Person("アンディ・ラウ",43,185)); list.add(new Person("周星驰",38,177)); list.add(new Person("郭富城",23,170)); /*Collections.sort(リスト、新しいComparator<Person>() { @オーバーライド パブリック int 比較(Person o1、Person o2) { o1.getAge()-o2.getAge() を返します。 } }); for (人 人 : リスト) { System.out.println(人); }*/ System.out.println("------"); Collections.sort(リスト、(Person o1、Person o2) -> { o1.getAge() - o2.getAge() を返します。 }); for (人 人 : リスト) { System.out.println(人); } } 出力
4. @FunctionalInterface アノテーション@FunctionalInterface は JDK8 で追加された新しい機能アノテーションであり、このアノテーションによって変更されたインターフェースには抽象メソッドが 1 つだけ存在できることを示します。 /** * @機能インターフェース * これは関数型アノテーションです。このアノテーションによって変更されるインターフェースは、抽象メソッドを 1 つだけ宣言できます。*/ @機能インターフェース パブリックインターフェースUserService{ void 表示(); } 5. ラムダ式の原理匿名内部クラスの本質は、コンパイル中にクラス ファイルを生成することです。 XXXXX$1クラス パブリッククラスDemo01Lambda { パブリック静的voidメイン(String[] args) { // 新しいスレッドを開始します new Thread(new Runnable() { @オーバーライド パブリックボイド実行() { System.out.println("新しいスレッドで実行されたコード: "+Thread.currentThread().getName()); } })。始める(); System.out.println("メインスレッドのコード: " + Thread.currentThread().getName()); System.out.println("---------------"); /*new Thread(() -> { System.out.println("新しいスレッド ラムダ式..." +Thread.currentThread().getName()); }) 。始める();*/ } } 逆コンパイルツールを使って生成されたコードを表示することもできます。XJadツールを使って表示することもできます。 静的クラス Demo01Lambda$1 Runnableを実装する { パブリック void 実行() { System.out.println((new StringBuilder()).append("新しいスレッドで実行されたコード: " ).append(Thread.currentThread().getName()).toString()); } デモ01ラムダ$1() { } } では、ラムダ式の原理とは何でしょうか?また、逆コンパイルツールを使ってチェックします ラムダ式を含むクラス ファイルの場合、XJad を使用してエラーをチェックします。このとき、JDK に付属するツール javap を使用してバイトコードを逆アセンブルすることができます。 javap -c -p ファイル名.クラス
分解の結果: E:\workspace\OpenClassWorkSpace\JDK8Demo\target\classes\com\bobo\jdk\lambda>javap -c -p Demo03Lambda.class 「Demo03Lambda.java」からコンパイル パブリッククラス com.bobo.jdk.lambda.Demo03Lambda { パブリック com.bobo.jdk.lambda.Demo03Lambda(); コード: 0: ロード_0 1:invokespecial #1 // メソッド java/lang/Object."<init>":()V 4: 戻る パブリック静的 void main(java.lang.String[]); コード: 0:invokedynamic #2, 0 // InvokeDynamic #0:show:()Lcom/bobo/jdk/lambda/service/UserService; 5:invokestatic #3 // メソッド goShow:(Lcom/bobo/jdk/lambda/service/UserService;)V 8: 戻る パブリック静的 void goShow(com.bobo.jdk.lambda.service.UserService); コード: 0: ロード_0 1: 呼び出しインターフェース #4, 1 // インターフェースメソッド com/bobo/jdk/lambda/service/UserService.show:()V 6: 戻る プライベート静的void lambda$main$0(); コード: 0: getstatic #5 // フィールド java/lang/System.out:Ljava/io/PrintStream; 3: ldc #6 // 文字列 Lambda show メソッドが実行されます... 5:invokevirtual #7 // メソッド java/io/PrintStream.println:(Ljava/lang/String;)V 8: 戻る } この逆コンパイルされたソース コードには、静的メソッド lambda$main$0() があります。このメソッドは何を行うのでしょうか?デバッグで確認してみましょう: 上記の効果は次のように理解できます。 パブリッククラスDemo03Lambda { パブリック静的voidメイン(String[] args) { .... } プライベート静的void lambda$main$0(); System.out.println("Lambda show メソッドが実行されました..."); } } これをより直感的に理解するには、実行時に-Djdk.internal.lambda.dumpProxyClassesを追加します。このパラメータを追加すると、内部クラスコードがファイルに出力されます。 コマンド実行 E:\workspace\OpenClassWorkSpace\JDK8Demo\target\classes>java -Djdk.internal.lambda.dumpProxyClasses com.bobo.jdk.lambda.Demo03Lambda 逆コンパイルされたコンテンツ: この匿名内部クラスは UserService インターフェースを実装し、show() メソッドをオーバーライドしていることがわかります。 showメソッドでは、Demo03Lambda.lambda$main$0()が呼び出され、Lambda内のコンテンツが呼び出されることになります。 パブリッククラスDemo03Lambda { パブリック静的voidメイン(String[] args) { goShow(新しいUserService() { @オーバーライド パブリックボイドショー(){ Demo03Lambda.lambda$main$0(); } }); System.out.println("-----------"); } パブリック静的void goShow(UserService userService){ ユーザーサービスを表示します。 } プライベート静的void lambda$main$0(); System.out.println("Lambda show メソッドが実行されました..."); } } まとめ: 匿名内部クラスは、コンパイル時にクラス ファイルを生成します。 ラムダ式は、プログラムの実行時にクラスを形成します。
6. ラムダ式の省略形ラムダ式の標準的な記述に基づいて、省略記号を使用するルールは次のとおりです。
パブリッククラスDemo05Lambda { パブリック静的voidメイン(String[] args) { goStudent((文字列名、整数年齢)->{ 名前+年齢+" 6666 ..."を返します。 }); // 省略形 goStudent((name,age)-> name+age+" 6666 ..."); System.out.println("------"); goOrder((文字列名)->{ System.out.println("--->" + 名前); 666を返します。 }); // 省略表記 goOrder(name -> { System.out.println("--->" + 名前); 666を返します。 }); goOrder(名前 -> 666); } パブリック静的void goStudent(StudentService studentService){ studentService.show("张三",22); } パブリック静的 void goOrder(OrderService orderService){ orderService.show("Li Si"); } } 7. ラムダ式を使用するための前提条件ラムダ式の構文は非常に簡潔ですが、気軽に使用できるわけではありません。ラムダ式を使用する際には、特に注意が必要な条件がいくつかあります。
8. ラムダクラスと匿名内部クラスの比較ラムダクラスと匿名内部クラスの比較 1. 必要なタイプが異なる
2. 抽象メソッドの数が異なる
3. 実施原則が異なる
ラムダ式の原理と例についての記事はこれで終わりです。ラムダ式についてさらに詳しく知りたい方は、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Ubuntu 18.04 システムでの Redis および phpredis 拡張機能のインストールと設定の詳細な説明
>>: MySQL 8.0.18 インストール構成の最適化チュートリアル
HTML タグには、インライン要素とブロックレベル要素の 2 種類があります。まず、インライン要素と...
インターネット上には、expect を使用して自動ログインを実現するスクリプトが多数存在しますが、明...
SSH 公開鍵認証は、SSH 認証方式の 1 つです。 SSH パスワードフリーのログインは公開鍵認...
使用フレキシブル ボックスはフロントエンドの Web ページ レイアウトで重要な役割を果たしますが、...
nginx が proxy_pass を設定する場合、末尾に "/" がある U...
今日は、「ローテク」の問題について書きたいと思います。ちなみに、私は JavaScript Week...
目次1. 怠惰な2.トリム3.番号4.停止5. キャプチャ6.自分7.一度8.予防する9.ネイティブ...
ページが非常に長い場合は、下にさらにコンテンツがあることをユーザーに知らせるために矢印が必要になるこ...
システムをインストールした後、毎回いくつかのソフトウェアを再インストールする必要があります。ソフトウ...
ミニプログラムはユーザーの個人情報を収集してアップロードしましたが、拒否されました。こんにちは、ミニ...
スタイル シートは、ドキュメントの表示方法、発音方法、または入力方法を記述します。スタイル シートは...
1. 縦型テーブルと横型テーブル垂直テーブル: テーブル内のフィールドとフィールド値はキーと値の形式...
この記事の例では、jsでテーブルを動的に追加および削除するための具体的なコードを参考までに共有してい...
フロントエンドがインターフェースを要求すると、バックエンドでインターフェースが定義されます。ステータ...
ウェブサイトのモバイル版には、少なくともいくつかの基本機能が必要です。 1. ページの適用性の問題:...