Java Lambda Expressionsは、Java 8によって導入された新機能です。シミュレートされた機能プログラミングの構文砂糖と言えます。それらはJavaScriptの閉鎖に似ていますが、やや異なっています。主な目的は、機能的な構文を提供してエンコードを簡素化することです。
Lambda Basic構文
ラムダの基本構造は(引数) - >ボディであり、いくつかの状況があります。
ボディは{}のステートメントを含める必要があり、{}は1つのステートメントしかない場合に省略できます。
一般的なライティング方法は次のとおりです。
(a) - > a * a
(int a、int b) - > a + b
(a、b) - > {return a -b;}
() - > system.out.println(thread.currentthread()。getId())
functionalinterface
コンセプト
Java Lambda式は、機能的なインターフェイスに基づいています。機能的なインターフェイスとは何ですか?簡単に言えば、1つのメソッド(関数)のみのインターフェイスです。このタイプのインターフェイスの目的は、単一の機能に相当する単一の操作です。 RunnableやComparatorなどの一般的なインターフェイスは機能的なインターフェイスであり、@FunctionAlinterfaceで注釈が付けられています。
例を挙げてください
例としてスレッドを使用することは簡単に理解できます。実行可能なインターフェイスは、プログラミングをスレッドするときに一般的に使用されるインターフェイスです。これには、スレッドの実行ロジックであるMethod void run()が含まれます。以前の構文によると、通常、実行可能な匿名クラスを使用して、次のように新しいスレッドを作成します。
new Sthrea(new runnable(){@Override public void run(){system.out.println(thread.currentthread()。getId();}})。start();書きすぎたら、退屈ではありませんか? Lambdaに基づく執筆ルールは、次のように簡潔で明確になります。
new shood(() - > system.out.println(thread.currentthread()。getId()))。start();
スレッドのパラメーターに注意してください。 Runnableの匿名の実装は1つの文で実装されており、よりよく理解するために次の文で記述されています。
runnable r =() - > system.out.println(thread.currentthread()。getId());
新しいスレッド(r).start();
もちろん、ラムダの目的は、簡潔に書くことだけでなく、それを理解した後の高レベルの目的を要約することです。
コンパレータの別の例を見てみましょう。従来の執筆方法によると、次のように:
integer [] a = {1、8、3、9、2、0、5}; arrays.sort(a、new Comparator <integer>(){@Override public int Compare(integer o1、integer o2){return o1 -o2;}});ラムダ式は次のように書かれています。
integer [] a = {1、8、3、9、2、0、5};
arrays.sort(a、(o1、o2) - > o1 -o2);
JDKの機能インターフェイス
既存のクラスライブラリがラムダ式を直接使用するためには、Java 8には機能的なインターフェイスとしてマークされていたいくつかのインターフェイスがありました。
新しいパッケージjava.util.functionがJava 8に追加され、一般的に使用される機能インターフェイスがもたらされました。
In addition, more specific functions are added to the processing of basic types, including: BooleanSupplier, DoubleBinaryOperator, DoubleConsumer, DoubleFunction<R>, DoublePredicate, DoubleSupplier, DoubleToIntFunction, DoubleToLongFunction, DoubleToLongFunction, DoubleUnaryOperator, IntBinaryOperator, IntConsumer, IntFunction<R>, IntPredicate,誤って、inttodoublefunction、inttolongfunction、intunaryoperator、longbinaryoperator、longconsumer、longfunction <r>、longtowsiperial、longtodoublefunction、longtointfunction、longunaryoperator、doublebifunction <t、doublebifunct、au> u>、tointfunction <t>、tolongbifunction <t、u>、tolongFunction <t>。上記の機能インターフェイスと組み合わせることで、これらの基本的な機能インターフェイスのクラス名を一目でインターフェイスの役割を見ることができます。
機能的なインターフェイスを作成します
機能的なインターフェイスを自分で実装する必要がある場合があり、この方法は非常に簡単です。まず、このインターフェイスには1つの関数操作のみができることを確認し、次にインターフェイスタイプに@FunctionAlinterInterfaceを注釈付けする必要があります。
タイプ派生
タイプの導出はラムダ式の基礎であり、型導入のプロセスはラムダ式の編集プロセスです。次のコードは例です。
function <string、integer> strtoint = str-> integer.parseint(str);
編集中、私が理解している型導入のプロセスは次のとおりです。
ここのターゲットタイプがキーであり、メソッドの署名はターゲットタイプを通じて取得され、それをラムダ式と比較します。
メソッド参照
メソッドリファレンス(メソッド参照)の基礎は機能的なインターフェイスでもあり、機能インターフェイスとして直接実装でき、ラムダ式と同じ機能を持ち、型導出にも依存します。メソッド参照は、1つの方法のみを呼び出すラムダ式の単純化と見なすことができます。
メソッドで参照される構文は次のとおりです。Type:: MethodNameまたはInstancename :: MethodName、およびコンストラクターに対応するMethodNameは新しいです。
たとえば、例は上で使用されました。
function <string、integer> strtoint = str-> integer.parseint(str);
対応するメソッド参照はです
function <string、integer> strtoint = integer :: parseint;
メソッドのタイプに応じて、メソッド参照は主に次のタイプに分けられます:コンストラクターメソッド参照、静的メソッド参照、インスタンスのインスタンスメソッド参照、タイプのインスタンスメソッド参照など。
コンストラクターメソッド参照
構文は:type :: newです。たとえば、次の関数は、文字列を配列に変換することです
メソッドリファレンスライティング
function <string、integer> strtoint = integer :: new;
ラムダの執筆
function <string、integer> strtoint = str-> new Integer(str);
伝統的な文章
function <string、integer> strtoint = new function <string、integer>(){@override public integer apply(string str){return new Integer(str); }};
配列コンストラクターリファレンス
構文は次のとおりです。Type[] :: new。たとえば、次の関数は、指定された長さの文字列配列を作成することです
メソッドリファレンスライティング
function <integer、string []> sixedArray = string [] :: new;
メソッドリファレンスライティング
function <integer、string []> sixedArray = length-> new String [length];
伝統的な文章
function <integer、string []> sixedArray = new function <integer、string []>(){@override public string [] apply(integer length){return new string [length]; }};静的メソッド参照
構文は:type :: newです。次の関数は、文字列を配列に変換するためにも使用されるため
メソッドリファレンスライティング
function <string、integer> strtoint = integer :: parseint;
ラムダの執筆
function <string、integer> strtoint = str-> integer.parseint(str);
伝統的な文章
function <string、integer> strtoint = new function <string、integer>(){@override public integer apply(string str){return integer.parseint(str); }};インスタンスのインスタンスメソッド参照
構文は:instancename :: methodnameです。たとえば、次の判断関数を使用して、指定された名前がリストに存在するかどうかを判断します
List <String> names = arrays.Aslist(new String [] {"Zhang San"、 "li si"、 "wang wu"});
Predicate <string> checknameExists = names :: contains;
System.out.println(checknameExists.test( "Zhang San"));
system.out.println(checknameexists.test( "zhang si"));
タイプのインスタンスメソッド参照
構文は次のとおりです。Type:: MethodName。ランタイムリファレンスは、文字列の長さを返すための以下の関数など、コンテキスト内のオブジェクトを指します
function <string、integer> calcstrlength = string :: length; system.out.println(calcstrlength( "zhang san")); list <string> names = arrays.aslist(new string [] {"zhangsan"、 "lisi"、 "wangwu"}); names. foreead:foread(foreead);
たとえば、次の関数は、文字列を配列に分割するためのセパレーターを指定しました
bifunction <string、string、string []> split = string :: split;
string [] names = split.Apply( "Zhangsan、Lisi、Wangwu"、 "、");
system.out.println(arrays.toString(names));
ストリーミングオブジェクト
コンセプト
ストリームとは何ですか?ここのストリームは、IOのinputstreamやoutputstreamとは異なります。ストリームはパッケージJava.util.Streamにあり、Java 8にも新しく追加されています。ストリームは、コレクションまたはイテレーターの拡張バージョンとして理解できるシリアル並列集約操作をサポートする要素のセットにすぎません。集約操作とは何ですか?簡単な例を挙げると、一般的な例には、平均、最大、最小、合計、並べ替え、フィルタリングなどが含まれます。
ストリームのいくつかの機能:
単一の処理。 1つの処理が完了すると、現在のストリームが閉じられます。
並列操作でストリームを取得する一般的な方法をサポートします
コレクションから入手してください
collection.stream();
collection.parallelStream();
静的工場
arrays.stream(array)
stream.of(t…)
intstream.range()
ここでは、ストリームの簡単な紹介のみを示します。以下に特定のアプリケーションがあります。ストリームとラムダの表現の関係について話したい場合、実際には特に密接な関係はありません。それは、ラムダの表現がストリームの使用を大いに促進するということです。ラムダの表現がなければ、ストリームの使用中に多数の匿名クラスが生成されますが、これは非常に厄介です。
例を挙げてください
次のデモは、従業員オブジェクトと従業員オブジェクトで構成されるリストオブジェクトによって異なります。
パブリッククラスの従業員{プライベート文字列名;プライベートストリングセックス;プライベートインクエイジ;公務員(文字列名、文字列セックス、int age){super(); this.name = name; this.sex = sex; this.age = age; } public string getname(){return name; } public string getSex(){return sex; } public int getage(){return age; } @Override public String toString(){StringBuilder Builder = new StringBuilder(); Builder.Append( "Employee {name =")。append(name).append( "、sex =")。append(sex).append( "、age =")。 return builder.toString(); }} list <employee> employees = new arrayList <>();従業員(新しい従業員( "Zhang San"、 "Male"、25));従業員(新しい従業員( "li si"、 "female"、24));従業員(新しい従業員( "Wang Wu"、 "Female"、23)); employes.Add(new Employee( "Saturday"、 "Male"、22)); employees.Add(新しい従業員( "Sun qi"、 "女性"、21)); employees.Add(新従業員( "Liu ba"、 "MALE"、20));すべての従業員を印刷します
コレクションは、個々のオブジェクトを1つずつ操作するためのforeachメソッドを提供します。
従業員(e-> System.out.println(e));
または
employess.stream()。foreach(e-> system.out.println(e));
年齢別に並べ替えます
collections.sort(従業員、(e1、e2) - > e1.getage() - e2.getage());
従業員(e-> System.out.println(e));
または
employes.stream()。sorted((e1、e2) - > e1.getage() - e2.getage())。
最年長の女性従業員を印刷します
最大/minは、指定されたソート条件下で最大/min要素を返します
従業員MaxageFemaleEmployee = employes.stream().filter(e-> "female" .equals(e.getsex())).max((e1、e2) - > e1.getage() - e2.getage()).get(); system.out.println(maxagefemalemolipereee);
20歳以上の男性従業員を印刷します
基準を満たす要素を除去します
従業員。stream()
.filter(e-> e.getage()> 20 && "male" .equals(e.getsex()))
.foreach(e-> system.out.println(e));
最古の2人の男性従業員を印刷します
Limitメソッドは、限られた要素をインターセプトします
employes.stream().filter(e-> "male" .equals(e.getsex())).sorted((e1、e2) - > e2.getage() - e1.getage()).limit(2)。
すべての男性従業員の名前を印刷し、使用する、別々
指定された関数を実行した後、新しいストリームを形成するためにマップします。
String MALEEMPLOYESEESNAMES = Employees.Stream().Map(e-> e.getName()).collect(collectors.jaining( "、")); system.out.println(maleEmployeSnames);
統計情報
intsummarystatistics、doublesummarystatistics、longsummarystatatisticsには、ストリーム内の概要データが含まれています。
intsummarystatistics stat = employees.stream().maptoint(employee :: getage).summarystatistics(); system.out.println( "従業員の総数:" + stat.getcount()); out.println( "最大年齢:" + stat.getmax()); stat.getmin()); system.out.println( "平均年齢:" + stat.getAverage());
要約します
ラムダの表現は、実際に多くのコードを減らし、生産性を向上させることができます。もちろん、欠点があります。つまり、複雑な表現は読みやすくなっていないか、それがあまり慣れていないためかもしれません。あなたがそれに慣れるなら、私はあなたがそれを好きになると信じています。すべてには2つの側面があり、特にチームの長所と短所のバランスをとる方法に依存します。
上記は、Java8 Javalambdaを整理する情報です。今後も関連情報を追加し続けます。このウェブサイトへのご支援ありがとうございます!