JavaのLambda式

4049 ワード

JavaのLambda式
1.Lambda式とは
簡単に言えば、Lambda式は匿名の方法です.Lambda式はプログラマがより簡潔なコードを使用できるようにするが,同様にコードの可読性を悪くする.
Lambda式は匿名メソッドや閉パッケージとも呼ばれます.
2.匿名の内部クラスと比較
Lambdaは匿名の方法で、この時私たちは匿名の内部クラスを考えて、私たちは匿名の内部クラスの使い方を思い出して、例えば以下のコードは匿名の内部クラスを使って1つのスレッドを実現しました.
public class Test {
  public static void main(String[] args) {
    Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("  :" + Thread.currentThread().getName());
      }
    });
    t.start();
  }
}

我々の一般的な方法はRunnableインタフェースの実装クラスを書き,new実装クラスをThreadのコンストラクタに渡すことである.次のようになります.
public class Test {

  public static void main(String[] args) {
    MyThread myThread = new MyThread();
    Thread t = new Thread(myThread);
    t.start();
  }

  static class MyThread implements Runnable {
    @Override
    public void run() {
      System.out.println("  :" + Thread.currentThread().getName());
    }
  }
  
}

匿名の内部クラスを使用すると、Runnableインタフェースの実装クラスを新規作成する手順は省略されていることがわかります.
3.Lambda式の使用
匿名の内部クラスの書き方を使用していますが、Lambda式を使用すると次のように書くことができます.
public class Test {
  public static void main(String[] args) {
    Thread t = new Thread(() ->  {
      System.out.println("  :" + Thread.currentThread().getName());
    });
    t.start();
  }
}

インタフェースに複数の方法がある場合、Lambda式はどのように実現方法を知っているのでしょうか.コードでテストします.
package com.wangjun.othersOfJava;

public class LambdaTest {

    public static void main(String[] args) {
        Animal a = () -> {  //     :The target type of this expression must be a functional interface
            System.out.println("    ");
        };
        a.eat();
    }
    interface Animal {
        public void eat();
        public void duty();
    }
}

コンパイルエラーが表示されます.functional interfaceといえば、関数インタフェースです.関数インタフェースは抽象的な方法が1つしかないインタフェースです.これにより,Lambda式は関数式インタフェースのみをサポートしていたことが理解できる.
4.Lambda式で使用されるいくつかの方法
package com.wangjun.othersOfJava;

public class LambdaTest {
    
    public static void main(String[] args) {
        
        //    
        Animal a1 = (String str) -> {
            System.out.println("    :" + str);
        };
        //     
        Animal a2 = (str) -> {
            System.out.println("    :" + str);
        };
        //     
        Animal a3 = str -> {
            System.out.println("    :" + str);
        };
        //      
        Animal a4 = str -> System.out.println("    :" + str);
        a1.eat("   ");
        a2.eat("  ");
        a3.eat("  ");
        a4.eat("  ");
        
        //   return  
        Person p1 = () -> {
            return "     :    !";
        };
        //     
        Person p2 = () -> "     :    !";
        System.out.println(p1.duty());
        System.out.println(p2.duty());
    }
    
    //      
    interface Animal {
        public void eat(String str);
    }
    //     
    interface Person {
        public String duty();
    }
}

4.Javaの二重コロン式
JDK 8には、メソッドをパラメータとしてstreamの内部に伝達し、streamの各要素をメソッドに伝達して実行する2つのコロンの使い方があります.二重コロンとLambda式の使用方法の違いをリストを巡回して説明します.
package com.wangjun.othersOfJava;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class LambdaTest {
    
  public static void printStr(String str) {
    System.out.println(str);
  }

  public static void main(String[] args) {

    List list = Arrays.asList("aaa","bbb","ccc");
    // 1.       
    for(String str: list) {
      LambdaTest.printStr(str);
    }
    // 2.  Lambda     
    list.forEach(str -> {
      LambdaTest.printStr(str);
    });
    // 3.  ::  
    list.forEach(LambdaTest::printStr);
    //           ,         
    Consumer methodParam = LambdaTest::printStr; //    
    list.forEach(x -> methodParam.accept(x));//    accept
  }
}