6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Java8のラムダ式

Last updated at Posted at 2016-04-20

今更ですがJava8らしいコードでプログラミングしたいなーと思ったのでさわりの部分軽くまとめてみます。

Java8の主な新機能

  1. ラムダ式
  2. メソッド参照
  3. Stream API

今回はラムダ式について

ラムダ式

抽象メソッドが1つ定義されているインターフェースを「関数型インターフェース」といいます。
この関数型インターフェースを実装してインスタンスを生成するのが「ラムダ式」です。

Java8で追加されたメソッドにIterable#forEach()があります。
このIterable#forEach()が引数にとるConsumer super T> action

これは、accept(Object)を関数メソッドに持つ関数型インタフェースです。

とあるように関数型インターフェース。
ということでIterable#forEach()を利用して匿名クラスの書き方とラムダ式を比較してみたいと思います。

匿名クラスで書くと
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class Test {
  public static void main(String[] args) {
    String[] array = { "1", "2", "3" };
    List<String> list = Arrays.asList(array);
    Consumer<String> action = new Consumer<String>() {
      @Override
      public void accept(String t) {
        System.out.println(t);
      }
    };
    list.forEach(action);
  }
}

匿名クラスを書くのにあれこれと追加をしなければならないです。

ラムダ式で書くと
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class Test {
  public static void main(String[] args) {
    String[] array = { "1", "2", "3" };
    List<String> list = Arrays.asList(array);
    Consumer<String> action = (String t) -> {
      System.out.println(t);
    };
    list.forEach(action);
  }
}

簡単に書け・・・
あれ?どんな構造になってんだこれ?

ラムダ式の構造
(関数型インターフェースのメソッドの引数の型 関数型インターフェースのメソッドの引数) -> {処理;}

この構造を意識して匿名クラスの部分とラムダ式の部分を見比べてみる。

匿名クラスの部分
    Consumer<String> action = new Consumer<String>() {
      @Override
      public void accept(String t) {
        System.out.println(t);
      }
    };
ラムダ式の部分
    Consumer<String> action = (String t) -> {
      System.out.println(t);
    };

引数と中の処理は残し
newする部分とメソッド名の宣言は省略され
->(アロー記号)を間に挟んでいる。

省略したラムダ式の書き方

実はラムダ式は以下のルールに従い更に省略ができる。

  • コンパイラの推論が働く場合は引数の型は不要
ラムダ式(型推論)
    list.forEach((t) -> {System.out.println(t);});

Iterable#forEach()の動作は以下のようになる

引用
for (T t : this)
    action.accept(t);

List<String>の場合は中はStringという推論がはたらくので
上の「t」の型「String」が省略できるようになる。

  • 型の省略をしたのち引数を囲むカッコは引数が1つなら省略できる
ラムダ式(引数1つ)
    list.forEach(t -> {System.out.println(t);});
  • 処理が1つの式で完結する場合

    • 値を返さないメソッドなら、処理が1つの式で完結する場合、ブロック記号({})や式のセミコロンは省略でき
    ラムダ式(処理1つ)
    list.forEach(t -> System.out.println(t));
    
    • 値を返すメソッドなら、処理がreturnの1つの式で完結する場合、更にreturnも省略できる

理解が間違っている部分などありましたらコメントいただけますと嬉しいです。

参考

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?