0.はじめに
伝えたいこと
- Java8のナウで便利な記法を知っておきましょう
前提知識
- Javaのforループ、無名関数
参考図書
『Java本格入門
~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで』技術評論社
特に指定がない限り、この本を引用しています。
目次
1. ラムダ式
ラムダ式とは
ラムダ式は、メソッドの引数などに処理そのものを渡すことができるかのような、強力な記法です。
※『Java 本格入門』P151 引用
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 3, 2, 1, 4, 5);
//ラムダ式を使わない書き方(無名クラス)
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
//ラムダ式を使った書き方
Collections.sort(list,
(o1, o2) -> Integer.compare(o1, o2)
);
ラムダ式は「無名クラスの実装メソッドが簡単に書ける」だけだが、後述のStream APIと組み合わせると、分かりやすい表記ができる。
[補足] 無名クラス
イベントリスナーの設定でよく使う。
//Androidで、クリックイベントを設定する場合の書き方
findViewById(R.id.hogehoge).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// クリック時の処理
}
});
関数型インターフェイスの代替として使用する
-
関数型インターフェース:抽象メソッドが1つのみのインターフェース
-
[Try] JavaDocを確認。 JavaDoc Comparator
-
関数型インターフェースは、ラムダ式に置き換えられる
ラムダ式の基本文法
- 基本文法:
(引数) -> { 処理}
- 条件によって、いろいろ省略できる
- 引数部分の型
- 引数の丸括弧(引数が1個のとき)
-
return
と波括弧(処理が1つのとき)
//ラムダ式の基本文法
Collections.sort(list,
(Integer o1, Integer o2) -> {
return Integer.compare(o1, o2);
}
);
//引数の型を省略
Collections.sort(list,
(o1, o2) -> {
return Integer.compare(o1, o2);
}
);
//引数の型と、return、波括弧を省略
Collections.sort(list,
(o1, o2) -> Integer.compare(o1, o2)
);
メソッド参照
メソッドそのものも代入できる。
List<String> list = Arrays.asList("X", "Y", "Z");
//メソッド参照を使った書き方
list.forEach(System.out::println);
//ラムダ式を使った書き方
list.forEach(str -> System.out.println(str));
forEach
メソッドの引数は、java.util.function.Consumer
という関数型インターフェース。
2.Stream API
Stream APIとは?
Stream APIは、大量データを逐次処理する「ストリーム処理」を効率的に記述するための手段として導入されました。
※『Java 本格入門』 P150引用
List<Integer> list = Arrays.asList(100, 60, 30, 50, 70);
list.stream() //Streamインスタンス生成
.filter(s -> s>=70) //中間操作。//70以上を抽出。
.forEach(s -> System.out.println(s)); //終端操作。
TODO Streamの画像を表示
※ 参考サイト
http://www.oracle.com/technetwork/jp/articles/java/ma14-java-se-8-streams-2177646-ja.html
Stream APIの特長
Stream APIは「HowではなくWhatを記述するAPI」。
-
How: 個別の処理
-
What: 処理の目的
-
Stream APIはループ処理を書かずに、目的を書く
-
SQLと同じ考え。
Stream APIの分類
- Stream作成
- Streamの中間操作
- Streamの終端操作
Streamを作成するAPI
//ListやSetからStreamを作成
List<Integer> list = Arrays.asList(100, 60, 30, 50, 70);
list.stream() //Streamインスタンス生成
.forEach(System.out::println);
//数値範囲からStreamを作成
IntStream.range(1, 5) //末尾を含まない
.forEach(System.out::println);
IntStream.rangeClosed(1, 5) //末尾を含む
.forEach(System.out::println);
Streamに対する中間操作
List<Integer> list = Arrays.asList(10, 6, 3, 5, 7);
//map: 要素を別の値に置き換える
list.stream()
.map(s -> s * s)
.forEach(System.out::println);
//filter: 条件に合致した要素のみ絞り込む
list.stream()
.filter(s -> s>=7)
.forEach(System.out::println);
//sort:
list.stream()
.sorted((s1,s2) -> s2 - s1) //降順
.forEach(System.out::println);
Streamに対する終端操作
List<Integer> list = Arrays.asList(10, 6, 3, 5, 7);
//forEach: 要素に対してアクションを実行する
list.stream()
.forEach(System.out::println);
//collect: 結果を作成する
List<Integer> newList = list.stream()
.filter(s -> s>=7)
.collect(Collectors.toList());
//average: 平均を返す(集計操作)
list.stream()
.average();
関数型言語
JavaScriptも。。。