Java 8 Lambda式(一)Lambda式の基礎知識

5892 ワード

目次
1 Lambda式の概要
1.1 Lambda式は何ですか
1.2 Lambda式によるRunnableインタフェースの実装
2 Lambda式構文
2.1 Lambda式の基礎構文
2.2 Lambda式の基礎構文の拡張
2.3 Lambda式の簡略化
1 Lambda式の概要
1.1 Lambda式は何ですか
        JDK1.8は現在最も流行しているJDKバージョンで、このバージョンにはLamda式が導入されています.Lambda式はコードを簡略化し、私たちのコードをより優雅にすることができますが、Lambda式が「優雅」なのは、Lambda式を使用してインタフェースを簡潔に実現することができ、Lamdba式自体が匿名関数であるからです.
1.2 Lambda式によるRunnableインタフェースの実装
Javaでは、Runnableインタフェースを実装したオブジェクトをThreadクラス構築関数のパラメータとして作成できます.たとえば、次のコードなどです.
public class TestThread {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyTest());
        thread.start();
    }
}

class MyTest implements Runnable {
    @Override
    public void run() {
        System.out.println("      ");
    }
}

もちろん、以下のコードに示すように、匿名関数の形式でスレッドを作成して、コードの作成をより柔軟にすることもできます.
public class TestThread {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("      ");
            }
        });
        thread.start();
    }
}

上のコードでは、Runnableはインタフェースであり、newを直接使用してオブジェクトを作成したり、インタフェースのメソッドを実装したりする必要があります.ここで匿名関数です.匿名関数の実装では,以下のコードに示すようにLambda式を用いることができる.
public class TestThread {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
                System.out.println("      ");
        });
        thread.start();
    }
}

 
2 Lambda式構文
2.1 Lambda式の基礎構文
作成スレッドを使用してLambda式の使用方法を簡単に説明したが、ここではLambda式の基礎構文を詳細に説明する.
Thread thread = new Thread(() -> {
     System.out.println("      ");
});

このコードを参考にして
()はパラメータのリストを表し,Runnableインタフェースのrun()メソッドにはパラメータがないので()にはパラメータがない.
->Lambda式の演算子で、メソッドボディを指します.
{}:メソッドボディを記述します.
したがって、ここでnew Thread()のコードセグメントは、Runnableインタフェースの実装クラスを作成することを意味し、インタフェースにパラメータのない抽象的なメソッドrunを実装し、メソッド体はSystemである.out.println(「スレッドの内容を実行」)です.
なぜここにRunnableという名前のプログラムが現れていないのに、実装されているのはRunnbleインタフェースであることを知っていますが、このインタフェースに2つ以上の抽象クラスプログラムがあればどのように解析しますか?この2つの疑問に対して,まずThreadクラスのソースコード,すなわち次のコードセグメントを見ることができる.
public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

これはThreadクラスの単一パラメータの構築方法であり,パラメータはRunnableであるため,ここではLambda式プログラムを用いてここで実現したRunnbaleインタフェースを知ることができる.一方、1つのインタフェースに複数の抽象メソッドがあるという問題に対して、Lambda式には、インタフェースに1つの抽象メソッドがあり、Runnbleインタフェースに2つ以上の抽象メソッドがある場合は使用できません.さらに、Runnableインタフェースのソースコードを開くと、インターネットに注釈@FunctionalInterfaceがあり、名前からこの注釈の意味が関数式インタフェースであることがわかります.つまり、このインタフェースには1つの方法しかありません.そうしないと、エラーが発生します.
2.2 Lambda式の基礎構文の拡張
上ではclass Threadとinterface Runnableを例に抽象手法の無パラメータ,無戻り値の場合の実装を紹介し,Lambda式の基礎構文を紹介したが,ここではLambda式の構文を拡張して紹介する.
(1)パラメータで値を返さない抽象的な方法の例として,以下のコードに示すように,まずこのようなインタフェースを宣言する.
@FunctionalInterface
public interface NoReturnOneParamInterface {
    void test(int num);
}

Lambda表現式を使用してこのインタフェースの実装オブジェクトを作成し、このように書くことができます.
public class Test01 {
    public static void main(String[] args) {
        NoReturnOneParamInterface noReturnOneParamInterface = (int num) -> {
            System.out.println(num);
        };
        noReturnOneParamInterface.test(100);    //           100
    }
}

(2)2つのパラメータで,戻り値がない抽象的な方法の例として,インタフェース宣言および方法の実現方式を以下に示す.
@FunctionalInterface
public interface NoReturnTwoParamInterface {
    void test(int a, int b);
}
public class Test01 {
    public static void main(String[] args) {
        NoReturnTwoParamInterface noReturnTwoParamInterface = (int a, int b) -> {
            System.out.println(a + b);
        };
        noReturnTwoParamInterface.test(100, 1000);    //           1100
    }
}

(3)任意のパラメータ,戻り値がある抽象的な方法の例として,インタフェース宣言および方法の実現方式は以下の通りである.
@FunctionalInterface
public interface HasReturnTwoParamInterface {
    int test(int a, int b);
}
public class Test01 {
    public static void main(String[] args) {
        HasReturnTwoParamInterface hasReturnTwoParamInterface = (int a, int b) -> {
            System.out.println(a + b);
            return a + b;
        };
        int test = hasReturnTwoParamInterface.test(100, 1000);  //   int     1100
        System.out.println(test);
    }
}

2.3 Lambda式の簡略化
Lambda式はある程度コードを簡略化しており、上記の文法に基づいて簡略化された文法もあり、コード潔癖な人は好きかもしれません.
(1)パラメータタイプの略記
メソッドパラメータタイプはインタフェース定義時にすでに宣言されているため、コンパイル時にJVMはメソッドパラメータタイプを知ることができるので、Lambda式を使用してパラメータの匿名関数を書く場合は、変調パラメータタイプを省略することができます.もちろん、パラメータタイプを省くには、このメソッドのすべてのパラメータのタイプが書かれていない必要があります.そうしないと、コンパイルに通じません.例は、次のコードです.
public class Test01 {
    public static void main(String[] args) {
        HasReturnTwoParamInterface hasReturnTwoParamInterface = (a, b) -> {
            System.out.println(a + b);
            return a + b;
        };
        int test = hasReturnTwoParamInterface.test(100, 1000);  //   int     1100
        System.out.println(test);
    }
}

(2)方法体が1行しかない場合は括弧を省く
すなわち,抽象メソッドの実装に1つのセミコロンしかない場合,メソッド体を囲む括弧を省くことができ,以下のコードで示す.
public class Test01 {
    public static void main(String[] args) {
        NoReturnOneParamInterface noReturnOneParamInterface = (a) -> System.out.println("hello world");
        noReturnOneParamInterface.test(1000);
    }
}

カッコを省略し、唯一の文がreturnである場合は、returnキーワードを省略する必要があります.もちろん、returnキーワードを省略すると返されます.
(3)パラメータが1つしかない場合は、パラメータを囲む括弧を省く
そうですね.これでも運行できます.
public class Test01 {
    public static void main(String[] args) {
        NoReturnOneParamInterface noReturnOneParamInterface = a -> System.out.println("hello world");
        noReturnOneParamInterface.test(1000);
    }
}