山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

スッキリわかるJava入門 実践編 第6章 ラムダ式と関数オブジェクト

分かりやすJavaオブジェクト指向編を読み終えたので、放置していたスッキリわかるJava入門実践編をやっていきたいと思います。

第6章 ラムダ式と関数オブジェクト

Java8から新しく導入されたラムダ式について学びます。

関数オブジェクト

関数をオブジェクトして扱い、変数に代入する。

メソッドを変数に代入して呼び出す
import java.util.function.IntBinaryOperator;

public class Main {
    public static int sub (int a, int b) {
        return a - b;
    }
    public static void main(String[] args) {
        // subメソッドの変数を変数functionに代入する
        /* IntBinaryOperator:
        *  2つのint値オペランドに作用して
        * int値の結果を生成する演算を表します。
        * applyAsInt(int, int)を関数メソッドに持つ関数型インタフェース
        * オペランド: コンピュータの演算における値や変数のこと
       */
        IntBinaryOperator func = Main::sub;

        // 変数functionに格納されている処理ロジックを
        // 引数5と3で実行する
        int a = func.applyAsInt(5, 3);
        System.out.println("5 - 3 = " + a);
    }
}
関数格納用のインターフェースを宣言して利用
// MyFunction型を使えるようにするために、
// SAMインターフェースを定義する。
/* SAM(Single Abstract Method):
 * 1つしかインターフェースを含まない。
 */

public interface MyFunction {
    public abstract int call(int x, int y);
}

public class Main {
    public static int sub (int a, int b) {
        return a - b;
    }
    public static void main(String[] args) {
        MyFunction func = Main::sub;

        int a = func.call(6, 1);
        System.out.println("6 - 1 = " + a);
    }
}

ラムダ式

関数を利用するときに初めて関数の実体が生成されます。

省略記法が色々あります。

ラムダ式の外にある変数も利用することができます。関数の実体が生み出された時点で、アクセス可能なすべての変数を使用できます。

関数をその場で生み出し、代入し、呼び出す
import java.util.function.IntBinaryOperator;

public class Main {
    public static void main(String[] args) {
        // 2つの引数の差を求める処理の実態を生み出し、
        // 代入する
        IntBinaryOperator func = (int a, int b) -> {return a -b;};
        int a = func.applyAsInt(8, 3);
        System.out.println("8 - 3 = " + a);
    }
}

Streamによる関数の活用

メリットとして並列処理による効率化が図れます。

コレクションの拡張for文を書き換える
for(Integer i: list){
    System.out.println(i * 2)
}
// ↓
list.stream().forEach(i -> System.out.println(i * 2))
配列に対してStream処理を行う
public class Exec {
    public static void main(String[] args) {
        int [] data = {1, 2, 3};
        IntStream st = IntStream.of(data);
        st.forEach(i -> System.out.println(i * 2));
    }
}
並列処理
// List<Integer> list
list.parallelStream().forEach(i ->  System.out.println(i * 2));

参考サイト

java-beginner.com

builder.japan.zdnet.com

スッキリわかる Java入門 実践編 第2版 (スッキリシリーズ)

スッキリわかる Java入門 実践編 第2版 (スッキリシリーズ)