Lambda式に初めてさらされたのはTypeScript(JavaScriptのスーパーセット)であり、この方法ではなく、この方法の外側にTypeScriptのメソッドを作成することでした。それを使用した後、私は突然、ラムダがJDK8のヘビー級の新機能ではないことに気付きました。それで、私は関連する情報をチェックして記録したと感じました:
1。動作パラメーター化
要するに、動作パラメーター化とは、関数の本文にテンプレートのような一般的なコードのみが含まれていることを意味しますが、ビジネスシナリオで変化するいくつかのロジックはパラメーターの形で関数に渡されます。動作のパラメーター化を使用すると、プログラムがより一般的になり、頻繁な変更のニーズに対処できます。
プログラムを通じてAppleをフィルタリングする必要があると仮定して、ビジネスシナリオを考慮して、最初にAppleエンティティを定義します。
パブリッククラスApple {/** number*/private long id;/** color*/private color color;/** weight*/private float weight;/*ostion*/private string rigin; public apple(){} public apple(long color、float weight、string ogirin){this.id = id; thid id; this.color = coler; this.weight = weight;ユーザーの最初の需要は、単にプログラムを通じて緑のリンゴを除外することである可能性があるため、プログラムを通じてすぐに実装できます。
public static list <plersgreenapples(list <apple> apples){list <apple> filterapples = new arraylist <>(); for(final apple:apples){if(color.green.equals()){filterapples.add(apple);}} return filterples;}このコードはシンプルで、言う価値はありません。しかし、ユーザーがグリーンになる必要がある場合、コードの変更は単純であるように思われますが、判断条件の緑を赤に変更するだけです。しかし、別の問題を考慮する必要があります。変化する条件が頻繁に変更された場合、これは行われますか?それが単なる色の変更である場合、ユーザーに色判断条件を直接渡すことができ、判断方法のパラメーターは「審査されるセットとフィルタリングされる色」を変更できます。しかし、ユーザーが色を判断するだけでなく、体重、サイズなどを判断したい場合はどうでしょうか。判断を完了するために異なるパラメーターを追加できると思いますか?しかし、このようなパラメーターを渡すのは本当に良いことですか?ますます多くのフィルタリング条件があり、コンビネーションモードがますます複雑になる場合、すべての状況を考慮し、各状況に対応する対処戦略を持っている必要がありますか?この時点で、動作をパラメーター化し、フィルタリング条件を抽出し、パラメーターとして渡すことができます。この時点で、判断インターフェイスをカプセル化できます。
パブリックインターフェイスAppleFilter {/***フィルター要約** @Param Apple* @return*/boolean Accept(Apple Apple);}/***インターフェイスにフィルターを挿入** @param Apples* @Return*/public Static List <plertsApplesbyAppleFilter(リスト<Apple>リッター、Appleterフィルター) for(最終Apple Apple:Apples){if(filter.accept(Apple)){filterApples.add(apple);}} return filterapples;}上記の動作の抽象化の後、特定の呼び出しでフィルター条件を設定し、パラメーターとして条件をメソッドに渡すことができます。この時点で、匿名の内部クラスの方法を使用します。
public static void main(string [] args){list <apple> apples = new arraylist <>(); // filt apple list <apple> filterapples = filterapplesbyapplefilter(){@overridepublic boolean accept(apple apple){// filter red red red red red red red red redipler() Apple.getWeight()> 100;}});}この設計は、java.util.comparator、java.util.concurrent.callableなど、JDK内でよく使用されます。このタイプのインターフェイスを使用する場合、匿名クラスを使用して、特定の通話場所の関数の特定の実行ロジックを指定できます。ただし、上記のコードブロックからは、非常にオタクですが、十分に簡潔ではありません。 Java8では、Lambdaを通じて単純化できます。
//フィルターAppleリスト<Apple> FilterApples = FilterApplesByAppleFilter(Apples、(Apple Apple) - > Color.Red.Equals(Apple.getColor())&& Apple.getWeight()> = 100); //() - > XXX()はメソッドパラメーター、XXXはメソッド実装です。
2。ラムダの表現定義
Lambda式を簡潔で可能な匿名関数として定義できます。まず、ラムダの表現が本質的に関数であることを明確にする必要があります。特定のクラスに属していませんが、パラメーターリスト、関数本体、リターンタイプ、および例外をスローする機能があります。第二に、それは匿名であり、ラムダの式には特定の関数名がありません。ラムダ式はパラメーターのように渡すことができ、それによりコードの書き込みを大幅に簡素化できます。形式の定義は次のとおりです。
フォーマット1:パラメーターリスト - >式
フォーマット2:パラメーターリスト - > {式コレクション}
Lambda式は戻りのキーワードを意味するため、単一の式では、returnキーワードを明示的に記述する必要はありませんが、式がステートメントのコレクションである場合、returnを明示的に追加し、Curly Braces {}で複数の式を囲む必要があります。以下の例をいくつか見てみましょう。
//指定された文字列の長さを返す、暗黙的にreturnステートメント(string s) - > s.length()//常に未調査のメソッド()()() - > 42 //は、巻き毛のブレースに囲まれた複数の式(int x、int y) - > {int z = x * y; return x + z;}に囲まれています。3.機能的インターフェイスに基づいてLambda式を使用します
ラムダ式の使用には、機能的なインターフェイスの助けが必要です。つまり、機能的なインターフェイスが表示された場合にのみ、ラムダ式でそれらを単純化できます。
カスタム機能インターフェイス:
関数インターフェイスは、抽象的なメソッドが1つしかないインターフェイスとして定義されます。 Java8のインターフェイス定義の改善は、デフォルトのメソッドを導入して、インターフェイス内のメソッドのデフォルトの実装を提供できるようにすることです。ただし、デフォルトメソッドの数が存在する場合、抽象的なメソッドが1つだけある限り、次のように機能的なインターフェイスです(上記のAppleFilterを参照):
/*** Apple Filter Interface*/ @functionalinterfacepublicインターフェイスAppleFilter {/***フィルター条件要約** @param Apple* @return*/boolean Accept(Apple Apple);}AppleFilterには、抽象的なメソッドAccept(Apple Apple)のみが含まれています。定義によれば、それは機能的なインターフェイスと見なすことができます。定義するときに、@FunctionAlinterfaceアノテーションをインターフェイスに追加して、インターフェイスを関数インターフェイスとしてマークします。ただし、このインターフェイスはオプションです。このインターフェイスを追加した後、コンパイラはインターフェイスを抽象的なメソッドのみを持つように制限します。そうしないと、エラーが報告されるため、このアノテーションを機能インターフェイスに追加することをお勧めします。
JDKには機能的なインターフェイスが付属しています。
JDKは、豊富な機能インターフェイスを備えたラムダの表現です。以下は、それぞれ述語<t>、消費者<t>、関数<t、r>の使用の例です。
述語:
@functionalinterfacepublic interface presticate <t> {/***指定された引数でこの予測を評価します。述語の機能は、上記のAppleFilterに似ています。外部で設定した条件を使用して、着信パラメーターを検証し、検証結果ブール値を返します。以下は述語を使用して、リストコレクションの要素をフィルタリングします。
/**** @param list* @param predicate* @param <t>* @return*/public <t> list <t> filter(list <t> list、predicate <t> predicate){list <t> newlist = new ArrayList <t>();使用:
demo.filter(list、(string str) - > null!= str &&!str.isempty());
消費者
@functionalinterfacepublic interface Consumer <t> {/***指定された引数でこの操作を実行します。消費者は、パラメーターを受信しますが、値を返さない抽象関数を受け入れます。以下は、消費者を使用してコレクションを横断します。
/***コレクションのトラバーサルとカスタム行動を実行する** @param list* @param Consumer* @param <t>*/public <t> voidフィルター(リスト<t>リスト、消費者<t>消費者){for(final t t:list){consumer.accept(t);}}}上記の機能インターフェイスを使用して、文字列コレクションを反復し、空でない文字列を印刷します。
demo.filter(list、(string str) - > {if(stringutils.isnotblank(str)){system.out.println(str);}});関数
@functionalinterfacepublic interface function <t、r> {/***この関数は指定された引数に適用します。関数は変換操作を実行します。入力はタイプTのデータであり、タイプRのデータを返します。次のように機能してセットを変換します。
public <t、r> list <r>フィルター(リスト<t> list、function <t、r> function){list <r> newlist = new ArrayList <r>(); for(final t t:list){newlist.add(function.apply(t));} return newlist;}他の:
demo.filter(list、(string str) - > integer.parseint(str));
上記の機能インターフェイスは、論理操作のデフォルトの実装も提供します。 Java8インターフェイスのデフォルトメソッドを導入するときに、後でそれについて話しましょう〜
使用中に注意を払うべきこと:
タイプの推論:
エンコーディングプロセス中に、呼び出しコードがどの機能インターフェイスが一致するか疑問に思うことがあります。実際、コンパイラは、パラメーター、リターンタイプ、例外タイプ(存在する場合)などに基づいて正しい判断を下します。
特定の方法で呼び出すと、パラメーターのタイプを時々省略することができ、コードをさらに簡素化することができます。
//フィルターAppleリスト<Popple> FilterApples = FilterApplesByAppleFilter(Apple、(Apple Apple) - > Color.red.equals(Apple.getColor())&& Apple.getWeight()> = 100); //場合によっては、パラメータータイプを省略することもできます。 color.red.equals(apple.getColor())&& apple.getWeight()> = 100);
ローカル変数
Lambda式の上のすべての例は、その身体パラメーターを使用しています。次のように、Lambdaのローカル変数を使用することもできます。
int weight = 100; list <apple> filterApples = filterApplesbyAppleFilter(Apples、Apple-> color.red.equals(apple.getColor())&& apple.getWeight()> = weight);:
この例では、ラムダの局所的な可変重量を使用します。ただし、Lambdaのローカル変数を使用すると、変数を最終または実際に最終的に明示的に宣言する必要があります。これは主に、ローカル変数がスタックに保存され、ラムダ式が別のスレッドで実行されるためです。スレッドビューがローカル変数にアクセスすると、変数は変更またはリサイクルされる可能性があるため、最終的な変更後にスレッドの安全性の問題はありません。
IV。メソッドの引用
メソッド参照を使用すると、コードがより簡素化される可能性があります。この単純化により、コードがより直感的に見える場合があります。例を見てみましょう:
/* ...リンゴの初期化操作を省略* /// lambda expression liples.sort((Apple A、Apple B) - > float.compare(a.getweight()、b.getweight()));
メソッドリファレンスは、メソッドメンバーシップとメソッド自体を::を介して接続します。これは、主に3つのカテゴリに分かれています。
静的メソッド
(args) - > classname.staticmethod(args)
に変換します
className :: staticMethod
パラメーターの例の方法
(args) - > args.instancemethod()
に変換します
className :: InstanceMethod // classNameはタイプargsです
外部インスタンスメソッド
(args) - > ext.instancemethod(args)
に変換します
ext :: instancemethod(args)
参照:
http://www.codeceo.com/article/lambda-of-java-8.html
上記は、編集者が紹介した新しいJDK8機能のラムダ表現です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!