ホームページ  >  記事  >  Java  >  Java8でラムダ式を使用する方法

Java8でラムダ式を使用する方法

黄舟
黄舟オリジナル
2017-09-19 10:34:581290ブラウズ

Java8 の最も学ぶ価値のある機能はラムダ式です。次の記事では、Java8 学習チュートリアルでラムダ式の使用に関する関連情報を主に紹介しており、サンプル コードを通じて非常に役立ちます。みんなの勉強や仕事に一定の参照と学習価値があり、それを必要とする友人が編集者に従って一緒に学ぶことができます。

はじめに

前回の記事では、ラムダ式の構文、ラムダ式の使用シナリオ、ラムダ式を使用するメリットについて紹介しました。この記事では、ラムダ式の定義方法と使用方法、および他の言語と比較したJavaのラムダ式の特殊な仕様を例を示して説明します。

匿名内部クラスの使用例

まず、Java 8 が登場する前は、ラムダ式で実行できたことは、プログラミングを単純化するためにラムダ式を使用しても実行できることを明確にしましょう。
次の例では、条件に基づいてリストからリーダーを選択します。

TantanitReader の定義:


public class TantanitReader {
 private int age;
 private String loginName;
 private String realName;
 private String career;

 public TantanitReader() {
 }

 public TantanitReader(int age, String loginName, String realName, String career) {
 this.age = age;
 this.loginName = loginName;
 this.realName = realName;
 this.career = career;
 }

 public int getAge() {
 return age;
 }

 public void setAge(int age) {
 this.age = age;
 }

 public String getLoginName() {
 return loginName;
 }

 public void setLoginName(String loginName) {
 this.loginName = loginName;
 }

 public String getRealName() {
 return realName;
 }

 public void setRealName(String realName) {
 this.realName = realName;
 }

 public String getCareer() {
 return career;
 }

 public void setCareer(String career) {
 this.career = career;
 }

 @Override
 public String toString() {
 return "age:"+this.getAge()+",loginName:"+this.loginName
 +",realName:"+this.getRealName()+",career:"+this.getCareer();
 }
}

判定インターフェースの定義:


public interface Predicate<T> {
 boolean test(T t);
}

選択関数の定義:


public class SelectService<T> {
 public List<T> select(Collection<T> source, Predicate<T> predicate){
 List result = new LinkedList();
 for(T element:source){
  if (predicate.test(element)) {
  result.add(element);
  }
 }
 return result;
 }

}

成人読者と青少年 (10 歳を含む) を選択するための例を書く古い) リーダー:


public class TantanitReaderPredicateTest {


 public static void main(String[] args) {
 SelectService tantanitReaderSelectSerive
 =new SelectService<TantanitReader>();
 List<TantanitReader> source = new LinkedList<>();
 source.add(new TantanitReader(10,"jack","张三","学生"));
 source.add(new TantanitReader(18,"rose","李四","学生"));
 source.add(new TantanitReader(19,"mike","王五","程序员"));
 source.add(new TantanitReader(20,"jack","赵六","作家"));

 List<TantanitReader> audultReaders
 =tantanitReaderSelectSerive.select(source, new Predicate() {
  @Override
  public boolean test(Object o) {
  TantanitReader tantanitReader=(TantanitReader)o;
  return tantanitReader.getAge()>=18;
  }
 });
 System.out.println("tantanit.com 成年读者名单如下:");
 printTantanitReaders(audultReaders);

 System.out.println("tantanit.com 十多岁(包含 10 岁)成员如下:");
 List<TantanitReader> teenReaders
 =tantanitReaderSelectSerive.select(source, new Predicate() {
  @Override
  public boolean test(Object o) {
  TantanitReader tantanitReader=(TantanitReader)o;
  return tantanitReader.getAge()>=10 && tantanitReader.getAge()<=19;
  }
 });
 printTantanitReaders(teenReaders);
 }


 public static void printTantanitReaders(List<TantanitReader> tantanitReaders) {
 for (TantanitReader tantanitReader : tantanitReaders) {
  System.out.println(tantanitReader.toString());
 }
 }


}

実行後の出力結果は次のとおりです:


tantanit.com 成员读者名单如下:
age:18,loginName:rose,realName: 李四,career: 学生 
age:19,loginName:mike,realName: 王五,career: 程序员
age:20,loginName:jack,realName: 赵六,career: 作家
tantanit.com 十多岁(包含10 岁)成员如下:
age:10,loginName:jack,realName: 张三,career: 学生
age:18,loginName:rose,realName: 李四,career: 学生
age:19,loginName:mike,realName: 王五,career: 程序员

リーダーを 2 回選択すると、 new Predicate() が必要となり、テスト メソッドがオーバーライドされることがわかります。本当の違いは、実際には、


tantanitReader.getAge()>=18


tantanitReader.getAge()>=10 && tantanitReader.getAge()<=19

の判定ステートメントのみにあります。しかし、Java8以前では、ラムダ式がなかったため、この冗長性を許容することしかできませんでした。ラムダ式を使用してコードを簡素化するにはどうすればよいですか?

他の言語とは異なり、Java 開発者の既存のプログラミング習慣を考慮するために、ラムダ式を使用するメカニズムを設計する際に、Java 8 ではインターフェイスを使用する必要があり、使用されるインターフェイスは関数型インターフェイスでなければならないと規定されています。この例では、引き続き使用できます:


public interface Predicate<T> {
 boolean test(T t);
}

このインターフェイスには抽象メソッドが 1 つだけあるため (Java8 ではデフォルト メソッドが導入されており、デフォルト メソッドは特定の実装を持ち、抽象メソッドではありません)、関数型インターフェイスです。 。関数インターフェイスは @FunctionalInterface を使用して宣言することも、そうでないこともできます。ただし、追加後、コンパイラはコンパイル段階でインターフェイスが関数型インターフェイスの定義に準拠しているかどうかをチェックします。そのため、ここでは新しいインターフェイスを定義して @FunctionalInterface 宣言を追加します:


@FunctionalInterface
public interface PredicateFunction<T> {
 boolean test(T t);
}

を使用して SelectService メソッドを追加します。パラメータとしての PredicateFunction:


public List<T> select(Collection<T> source, PredicateFunction<T> predicate){
 List result = new LinkedList();
 for(T element:source){
 if (predicate.test(element)) {
  result.add(element);
 }
 }
 return result;
}

テスト例を再度変更します:


public class TantanitReaderPredicateFunctionTest {

 public static void main(String[] args) {
 SelectService tantanitReaderSelectSerive
 =new SelectService();
 List source = new LinkedList<>();
 source.add(new TantanitReader(10,"jack","张三","学生"));
 source.add(new TantanitReader(18,"rose","李四","学生"));
 source.add(new TantanitReader(19,"mike","王五","程序员"));
 source.add(new TantanitReader(20,"jack","赵六","作家"));

 PredicateFunction predicateFunction
  = (TantanitReader tantanitReader) -> tantanitReader.getAge() >= 18;
 List audultReaders
 =tantanitReaderSelectSerive.select(source,predicateFunction);

 System.out.println("tantanit.com 成员读者名单如下:");
 printTantanitReaders(audultReaders);

 System.out.println("tantanit.com 十多岁(包含 10 岁)成员如下:");
 PredicateFunction predicateFunction2
 = (TantanitReader tantanitReader)
 -> tantanitReader.getAge()>=10 && tantanitReader.getAge()<=19;
 List teenReaders
 =tantanitReaderSelectSerive.select(source,predicateFunction2);
 printTantanitReaders(teenReaders);
 }


 public static void printTantanitReaders(List tantanitReaders) {
 for (TantanitReader tantanitReader : tantanitReaders) {
  System.out.println(tantanitReader.toString());
 }
 }

}

このコードがどのように影響するかを分析してみましょう:


PredicateFunction<TantanitReader> predicateFunction
 = (TantanitReader tantanitReader) -> tantanitReader.getAge() >= 18;
List<TantanitReader> audultReaders
=tantanitReaderSelectSerive.select(source,predicateFunction);

このコードは、PredicateFunction 型のインスタンスを生成し、 TantanitReaderSelectSeriveのselectメソッドにパラメータとしてインスタンスの参照を指定し、selectメソッドを実行します。 select の実行中に、predicateFunction のテスト メソッドが呼び出され、テスト メソッドの内容は渡したラムダ式です。最後に、ラムダ式に従ってリーダーが選択されます。

さらに一歩進んで、通常は predicateFunction 変数を定義できませんが、次のようにラムダ式をパラメータとして TantanitReaderSelectSerive の select メソッドに直接渡すことができます:


List<TantanitReader> audultReaders
=tantanitReaderSelectSerive.select(
 source,(TantanitReader tantanitReader) -> tantanitReader.getAge() >= 18
);

しかし、この例ではコンパイル エラーが発生します。実際には TantanitReader の select メソッドがジェネリックスを使用しているため、tantanitReaderSelectSerive の select メソッドの定義と一致しないと報告されます。 Java 8 のドキュメントでは、ジェネリックスを使用する場合、ラムダ式をパラメータとして直接使用できないと規定していますが、これは非常に恥ずかしいことです。ジェネリックを使用しない場合、この問題は発生しません。

概要

ラムダ式の使い方をまとめました

  • まず、関数型インターフェース(関数型インターフェース)を定義し、インターフェース内で使用する必要がある抽象メソッドを定義します。

  • ビジネス メソッドを記述し、関数インターフェイスをパラメーターとして受け取り、インターフェイスによって定義されたメソッドを呼び出してビジネス ロジックを完成させます。

  • ビジネス メソッドを呼び出し、ラムダ式をパラメータとして渡します。

ジェネリックを使用する場合、最後のステップでは、まず関数型インターフェイスのインスタンスへの参照を定義し、それをパラメーターとしてビジネス メソッドに渡します。

さらに、ラムダ式は引き続き関数参照に単純化できます。これについては後の記事で説明します。

概要

以上がJava8でラムダ式を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。