Java 8--Lambda式(一)

6425 ワード

一、定義:
Lambda式はJava 8の中で最も主要な特性の一つである.Lambda式とは何ですか?簡単に言えば、Lambda式は匿名関数です.Javascriptや他の関数式プログラミングの経験がある人は、この概念をよく知っているはずです.しかし、単純にJavaの観点から見ると、この概念はまだよく知られていない.まず、Javaの関数は単独では存在せず、クラスに依存する必要があるため、関数の実行にはクラス名で呼び出す必要があり、1つのメソッドだけでもクラスを定義する必要があり、JDKにはRunnableインタフェースなどのこのようなインタフェースがたくさんあります.次に、JDK 1.8の前に、関数は値(オブジェクトの参照または基本タイプ)の伝達のみを行い、動作(関数/メソッド)を伝達することはできません.したがって,JavaでLambda式を実現することは困難である(どのように実現するかについては後述する).それなら、なぜLambda式を導入するのでしょうか.主な原因は
1、簡略化コード
2、効率を高める
3、Java 8のStreamの基礎を築く
私たちは後続の分析からこの3つの原因をよく見ることができます.
 
二、Lambda式の文法
まず最も簡単な列でLambda式を見てみましょう.
public class LambdaHelloWord {

    public void helloWorld(Runnable runnable){
        runnable.run();
    }

    public static void main(String[] args) {
        LambdaHelloWord lambda = new LambdaHelloWord();
        
        //JDK 1.8       
        lambda.helloWorld(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello,World!");
            }
        });

        //Lambda       
        lambda.helloWorld(()->System.out.println("Hello,World!"));
    }
}

 このコードには2つの方法でHello,Worldを印刷します.1つ目の方法はJDK 1.8以前に採用された方法で、Hello,Worldを印刷するために、複数行のテンプレートコードが必要です.Lambda表現を採用すれば、1行のコードで私たちが望んでいる機能を完成することができ、冗長なコードはありません.したがって、Lambda式はJavaコードの冗長な非難をある程度解決することができる.
上記の例では、Lambda式を詳しく分析します.Lambda式は3つの部分から構成されています.
1、パラメータリスト()は、Runableのrun()メソッドにはパラメータがないので、パラメータリストは空です.2、矢印記号->は、パラメータリストと関数トピック3、関数トピックSystem.out.println(「Hello,World!」)を分割し、私たちが完成する機能です.
 
三、関数インタフェース:
どのような場合にLambda式を伝えることができますか?すべての関数がLambda式を受信できるわけではないに違いない.上の例に戻ると、関数helloWorld()はRunnableパラメータを受信します.そのRunnableインタフェースの特徴は何ですか.--唯一の方法です.Java 8は、このような1つの方法しかないインタフェースを関数式インタフェースと呼び、関数式インタフェースタイプパラメータを受信する方法であればLambda式を受信することができる.Javaでよく見られる関数インタフェースには、Comparator、EventHandlerなどがあります.このほか、Java 8には多くの新しい関数プログラミングインターフェースが用意されています.
  • PredicateはTオブジェクトを受信しboolean
  • に戻る.
  • ConsumerはTオブジェクトを受信し、値
  • を返さない.
  • FunctionはTオブジェクトを受信し、Rオブジェクト
  • に戻る.
  • SupplierはTオブジェクトを提供し、値
  • を受信しない.
  • UnaryOperatorはTオブジェクトを受信し、Tオブジェクト
  • に戻る.
  • BinaryOperatorは2つのTオブジェクトを受信し、Tオブジェクト
  • に戻る.
    すべてのインタフェースはjava.util.functionパッケージの下にあり、上記のインタフェースのほかにも多くの関数インタフェースがありますが、機能は上記と似ています.
    関数インタフェースの定義に基づいて、私たちは簡単に自分の関数インタフェースを実現します(関数を含むインタフェースを定義すればいいです):
    public interface Operator {
        public int op(int i,int j);
    }

    これにより、Lambda式を使用してインタフェースを使用することができます.
    public class Test {
    
        public int compute(Operator operator,int i,int j){
            return operator.op(i,j);
        }
    
        public static void main(String[] args) {
            Test test = new Test();
            //    
            int add = test.compute((i,j)->i+j,10,20);
            System.out.println(add);
            //    
            int subtract = test.compute((i,j)->i-j,10,20);
            System.out.println(subtract);
            //    
            int multiply = test.compute((i,j)->i*j,10,20);
            System.out.println(multiply);
            //    
            int divide = test.compute((i,j)->{
                if(j==0){
                    throw new ArithmeticException();
                }
                return i/j;
            },100,20);
            System.out.println(divide);
        }
    }

    これにより,整数の4則演算を1つの方法で実現できる.除算操作を行う場合、除数を検証する必要があり、直接操作できないため、関数体をコードブロックに書きます.ただし、コードブロック({})を使用しない場合は、結果を返す必要はありません.コードブロックを使用する場合は、戻り値が必要です.
     四、まとめ
    Lambda式はJava 8の非常に重要な特性として、Javaのテンプレートコードを非常に効果的に減らすことができ、本質的に匿名の関数であり、関数のパラメータとして伝達することができ、これはC言語の関数ポインタと似ている.次の記事では,Lambda式がどのように実現されるかをJVMの観点から論じる.