LoginSignup
50
51

More than 5 years have passed since last update.

Java8 ラムダとStreamAPIを理解する

Posted at

目的

Java8で導入されたラムダとStreamAPIについていろいろ調べたのでメモする(すべてJavaの話です)

ラムダ式

  • ラムダ式は、関数型インターフェースを使ってラムダ計算を実装する構文
    • 関数型インターフェースは、一つのAbstractメソッドしか持たないインターフェースのこと
      • Comparator/Runnable/Function/Predicateなど
    • ラムダ計算は、識別子/無名関数/関数適用の3つの要素だけで式が表現される計算モデル
      • JavaではJVMで直接関数を扱うのではなく、クラスのインスタンスを使って表現している
  • 型推論で変数の型定義が省略できる。
    • 省略しなくてもいい。
      • 省略されすぎると、見慣れないため意味がわからない。
        • そのうち慣れる。
  • クロージャーではない。
    • ローカル変数は実質的にfinalな変数にしかアクセスできない。(変更できない)
    • 独自のスコープは持たない。(ローカル変数と同じ変数名は利用できない)
  • 無名内部クラス(匿名クラス)はラムダ式に置き換え可能(ほぼ問題なく(thisの扱いが違う))
    • 似ているが実行時の呼び出しが異なる。
      • ラムダは実行時にクラスが生成される
        • 匿名クラスのようにコンパイル時にクラスを生成するとクラスロードが遅くなるため
          • 2回目以降の呼び出しは速い
      • ラムダのインスタンスは、VMが最適な生成方法を選択するらしい。
        • JVMの実装によっては今後も改善される可能性あり。

StreamAPI

  • ラムダ式と組み合わせて使うパイプライン型のデータ処理を実現するAPI
    • メソッドチェーン形式で記述
  • ソース、中間操作、終端操作の3つの構成要素からなる。
    • ソース:list.stream()(1つだけ)
    • 中間操作:.map(User::name)(複数指定可能)
    • 終端操作:.collect(Collectors.toList());(1つだけ)
  • 並列化が容易
    • StreamAPIを利用しないで並列処理を書く場合にくらべコード量が減る
    • 遅延評価で処理速度アップ

メリット

  • コード量が減る
  • より直感的にコードを理解できる
  • 並列処理を気軽に実装できる
    • 現在の基盤の資源を最大限に活かすためには並列処理が必要

デメリット

  • forの構文とラムダ式が混ざるとコードの可読性は下がる。
  • すべてラムダで表現しようとするとコードの可読性は下がる(と思っている)
  • 並列化して速度が必ずしも上がるわけではない。(デメリットではないが)
  • 標準の関数型インターフェースを利用する場合は、例外を投げれないのでラムダの中で処理しなければならない。

参考文献

実はこれが大事

まずはざっと理解する

社内Java8勉強会 ラムダ式とストリームAPI
- この資料のStreamAPIまでの章を理解しておけば、うんちくが語れます。
ひしだま's 技術メモページ Javaラムダ式
- レイアウトがWeb1.0で読みにくいが実はわかりやすい
きしだのはてな Java8 Lambdaの文法拡張まとめ
- なんとなく頭に入りやすい。

より深く知る(概念系)

Java Day Tokyo Lambda: A Peek Under The Hood
- ラムダと内部クラスの違いをInvokedynamicからのバイトコード呼び出しとそのパフォーマンスを混じえて説明
IBM DeveloperWorks Java 8 言語での変更内容
- 文章が多い。さらなるうんちくをえるためには参考になった。
Java Day Tokyo Javaの関数型言語への挑戦/ベターオブジェクト指向言語からの脱皮
- Javaのラムダと関数型言語との違いをわかりやすく説明
関数型言語のウソとホント
- Javaには関係なく関数型プログラミング言語に関する記事。
- これを読むとJavaのラムダが中途半端で申し訳なくも感じる。

実用編

とにかく書き方を知りたい
ラムダ式と関数型インタフェース
Java8 StreamAPI
今更人に聞けないJava5からの新機能(Java SE 8)
(o1, o2) -> o1 - o2 なんて呪文はもうやめて! - Java8でのComparatorの使い方
- ソートについてはこれはわかりやすい

その他、ラムダですべてハッピーになれるわけはない

Java 8のStream APIの性能まとめ
forループからStream API移行に関する適当な感想

50
51
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
50
51