見出し画像

JavaSilverに向けて⑩ ラムダ式

・ラムダ式


クラスの宣言とインスタンスの生成を同時に行う文法。
  ー ラムダ式のメリット
関数型インターフェースを実装するためのソースを短く書ける。
Stream APIの引数としての関数型インターフェースを記述するのに適している。
*関数型インターフェース
抽象メソッドを1つ持つインターフェースの事。
*Stream API
配列やList, Collectionなどの要素の集合に対して、要素の直列処理や並列処理、要素の比較並び替え、一致判定などの処理を実行するメソッド群の事。

・ラムダ式の使い方


インターフェース名 オブジェクト名 = (引数1, 引数2, •••) -> {return 処理内容};
上記が、ラムダ式の基本的な形である。また、上記では型の記述がないが、型を記載してもエラーにはならない。
  ー ラムダ式の引数が1つの場合
インターフェース名 オブジェクト名 = 引数 ->  処理;
引数が1つの場合、処理結果を返すreturn句、{}、()を省略できる。
interface InterfaceSample {
    String process();
}
public class Sample {
    public static void main(String[] args) {
        InterfaceSample s = () -> “hello”;
        System.out.println(s.process());
    }
}
ラムダ式の処理が1つしかなく、何らかの戻り値を戻す場合は、return句を省略できるというよりも省略しなければならない。
上記の例を基に考えるのであれば、以下のようにreturn句を書くとコンパイルエラーとなる。
public class Sample {
    public static void main(String[] args) {
        InterfaceSample s = () -> return “hello”; //コンパイルエラー
        System.out.println(s.process());
    }
}
また、戻り値を戻すメソッドで、その処理を{}で括った場合、return句を記述しなければならず、return句を記述しなければコンパイルエラーとなる。
public class Sample {
    public static void main(String[] args) {
        InterfaceSample s = () -> { “hello”;}; //コンパイルエラー
        System.out.println(s.process());
    }
}

・関数型interfaceの実装をラムダ式に置き換える方法


interface InterfaceTest {
    public String method(String name, int n);
}
public class Main {
    public static void main(String[] args) {
        InterfaceTest it = (name, n) -> {
            return “Hello “ + name + n + “!”;
        }
        System.out.println(it.method(“Java”, 8);
    }
}

・Stream APIの引数にラムダ式を使う方法


List, Collectionなどのオブジェクト名.stream().メソッド名((引数) -> {処理})

・ラムダ式でのforEach


以下では、メソッド参照(System.out::println)を使って短く記述する事ができる。
public class Main {
    public static void main(String[] args) {
        Integer[] num = {1,2,3,4,5};
        List<Integer> l = Arrays.asList(num);
        l.forEach(System.out::println);
    }
}

・ラムダ式でのfilter


public class Main {
    public static void main(String[] args) {
        Integer[] num = {1,2,3,4,5};
        List<Integer> l = Arrays.asList(num);
        l.stream().filter(x -> x < 3).forEach(System.out::println);
    }
}

・ラムダ式の特徴


  ー ラムダ式内で変数の値の変更はNG
ラムダ式からローカル変数にアクセスする事が可能だが、そのラムダ式内でローカル変数を変更するとコンパイルエラーとなる。
interface InterfaceSample {
    void test();
}
public class Sample {
    public static void main(String[] args) {
        String str = “hello”;
        InterfaceSample s = () -> {
            str = “hello, hello”;  //コンパイルエラー
            System.out.println(str);
        };
        s.test();
    }
}

  ー ラムダ式の外であっても変数の変更はNG
ラムダ式が宣言したタイミングで実行されるわけではないため、宣言後であっても変更されるとコンパイルエラーとなる。
public class Sample {
    public static void main(String[] args) {
        String str = "hello";
        InterfaceSample s = () -> {
            System.out.println(str);
        };
        str = "hello, hello"; //コンパイルエラー
        s.test();
    }
}

・Function<T,R> 引数ありで戻り値あり


FunctionのTはメソッドの引数の型、Rはメソッドの戻り値の型。applyメソッドが使える。
public class Sample {
    public static void main(String[] args) {
        Function <Integer, String> f = a -> a + "です";
        String b = f.apply(2);
        System.out.println(b); //2です
    }
}

・Consumer<T> 引数ありで戻り値なし


ConsumerのTはメソッドの引数の型。acceptメソッドが使える。
public class Sample {
    public static void main(String[] args) {
        Consumer<Integer> c = a -> System.out.println(a + "です");
        c.accept(3); //3です
    }
}

・Predicate<T> 引数ありでbooleanの戻り値あり


PredicateのTはメソッドの引数の型。testメソッドが使え、booleanを戻す。
public class Sample {
    public static void main(String[] args) {
        Predicate<String> p = a -> a.isEmpty();
        boolean b = p.test("a");
        System.out.pritnln(b); //false
        boolean c = p.test("");
        System.out.println(c); //true
    }
}

・Supplier<T> 引数なしで戻り値あり


SupplierのTはメソッドの戻り値の型。getメソッドが使える。getメソッドは引数はないが戻り値はある。
public class Sample {
    public static void main(String[] args) {
        Supplier<String> s = () -> "hello";
        String a = s.get();
        System.out.println(a); //hello
    }
}

参照
https://engineer-club.jp/java-lambda-expression
https://www.sejuku.net/blog/22337
https://itsakura.com/java-lambda-function

この記事が気に入ったらサポートをしてみませんか?