java8 lambdas chapter1_2

21
Java8 Lambdas 勉強会 Chapter 1, 2 内藤 遥

Upload: yo0824

Post on 08-Jul-2015

111 views

Category:

Engineering


7 download

DESCRIPTION

Java8 lambdas chapter1_2

TRANSCRIPT

Page 1: Java8 lambdas chapter1_2

Java8 Lambdas 勉強会 Chapter 1, 2

内藤 遥

Page 2: Java8 lambdas chapter1_2

Table of Contents

1. Introduction • Why Did They Need To Change Java Again ? • What Is Functional Programming ? • Example Domain

2. Lambda Expressions • Your First Lambda Expression • How to Spot a Lambda in a Haystack • Using Values • Functional Interfaces • Type Inference • Key Points

Page 3: Java8 lambdas chapter1_2

• マルチコア化で処理性能向上を目指す時代 • java.util.concurrent パッケージなどを使った並行処理には限界がある

⇒ ラムダ式を使った関数型プログラミングで簡潔、かつ強力な並行処理の実装が書ける

• 関数型言語の利点 • 可読性

• 保守性

• バグが少ない

Why Did They Need To Change Java Again ?

Page 4: Java8 lambdas chapter1_2

• 文字通り「関数」を使用したプログラミング • 入力した値に対して必ず同じ結果を返す

• オブジェクト指向におけるメソッド(一連の手続きをまとめて名前を付けたもの)とは異なる

• 関数の特徴 • 参照透過性

• ある関数に同じ入力値を与えれば、いつ評価しても必ず同じ値が得られる

• 変数は一度定義したら二度と変えない(再代入操作で状態を書き換えない)

• 第一級関数

• 変数に代入したり、別の関数の引数や戻り値になったりすることができる

What Is Functional Programming ?

Page 5: Java8 lambdas chapter1_2

Example Domain

• 本全体を通して、例の提示には共通の問題領域として音楽が使われる

• 要約は以下の通り

• アーティスト – 曲を作る個人やグループ

• トラック • 一つの曲

• アルバム • 複数のトラックの集合

• 音楽は関数型プログラミングの手法を説明する際に使われる

Page 6: Java8 lambdas chapter1_2

Your First Lambda Expression

• Swing(JavaのGUIライブラリ)でボタンをクリックした際の、匿名クラスを用いたevent listenerの実装

• 不要な行が多い

• 読みにくい

button.addActionListener(new ActionListerner() { public void actionPerformed(ActionEvent event) { System.out.println("button clicked"); } });

Page 7: Java8 lambdas chapter1_2

Your First Lambda Expression

• ラムダ式を使用

• (メソッドの引数) -> (処理) の形で書ける

• メソッド名や引数の型が省略できる

button.addActionListener(event -> System.out.println("button clicked"));

Page 8: Java8 lambdas chapter1_2

Your First Lambda Expression • ラムダ式を使った様々な実装例

Runnable noArguments = () -> System.out.println("Hello world"); ActionListener oneArgument = event -> System.out.println("button clicked"); Runnable multiStatement = () -> { System.out.println("Hello"); System.out.pringln(" World"); }; BinaryOperator<Long> add = (x,y) -> x + y; BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;

Page 9: Java8 lambdas chapter1_2

Your First Lambda Expression • ラムダ式を使った様々な実装例

引数がないときは()のように書ける。戻り値の型はvoid

Runnable noArguments = () -> System.out.println("Hello world");

Page 10: Java8 lambdas chapter1_2

Your First Lambda Expression • ラムダ式を使った様々な実装例

引数が一つのときは左辺の()を省略できる。引数名は任意で指定可能

ActionListener oneArgument = event -> System.out.println("button clicked");

Page 11: Java8 lambdas chapter1_2

Your First Lambda Expression • ラムダ式を使った様々な実装例

処理が複数行に渡る場合は{}をつける

Runnable multiStatement = () -> { System.out.println("Hello"); System.out.pringln(" World"); };

Page 12: Java8 lambdas chapter1_2

Your First Lambda Expression • ラムダ式を使った様々な実装例

処理が一行の場合、returnを 省略できる(x + y の結果を返す処理の実装)

BinaryOperator<Long> add = (x,y) -> x + y;

Page 13: Java8 lambdas chapter1_2

Your First Lambda Expression • ラムダ式を使った様々な実装例

引数の型は省略せずにも書ける

BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;

Page 14: Java8 lambdas chapter1_2

Using Values

• 匿名クラスでは、finalのローカル変数、引数が扱える

• ラムダ式では、実質 finalのローカル変数、引数が扱える

• (場合によってはfinalが可読性を損なうこともあるため)

final String name = getUserName(); button.addActionListener(new ActionListerner(){ public void actionPerformed(ActionEvent event){ System.out.println("hi " + name); } });

String name = getUserName(); button.addActionListener(event -> System.out.println("hi " + name));

Page 15: Java8 lambdas chapter1_2

Using Values

• 下記の場合、 nameが実質finalでないのでコンパイルエラーとなる

String name = getUserName(); name = formatUserName(name); button.addActionListener(event -> System.out.println("hi " + name));

Page 16: Java8 lambdas chapter1_2

Functional Interfaces

• 関数型インターフェイスとは • 定義されている抽象メソッドが1つだけあるインターフェイス

• ラムダ式は、関数型インターフェイスに対して適用することができる

• 今後は、関数型インターフェイスをダイアグラムで表現する

• 関数に入っていく矢印は引数を、関数から出ていく矢印は戻り値の型を表す

• 関数型インターフェイスとダイアグラムの例は下記の通り

ActionListener

public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent event); }

ActionEvent

Page 17: Java8 lambdas chapter1_2

Functional Interfaces

• 関数型インターフェイスには、いくつかのコアグループがある

Interface name Arguments Returns Example

Predicate<T> T boolean Has this album been released yet?

Consumer<T> T void Printing out a value

Function<T, R> T R Get the name from an Artist Object

Supplier<T> None T A factory method

UnaryOperator<T> T T Logical not(!)

BinaryOperator<T> (T, T) T Multiplying two numbers(*)

Page 18: Java8 lambdas chapter1_2

Type Inference(型推論)

• Java7から、ダイヤモンド演算子を用いた型推論が可能

• メソッドの引数には型推論が使えなかったが、Java8から使えるようになった

Map<String, Integer> oldWordCounts = new HashMap<String, Integer>(); Map<String, Integer> diamondWordCounts = new HashMap<>();

useHashmap(new HashMap<>()); … private void useHashmap(Map<String, String> values);

Page 19: Java8 lambdas chapter1_2

Type Inference

• ラムダ式を使った型推論

• パラメータの型は省略可能

• javacで戻り値の型がbooleanであるかチェックしてくれる

Predicate<Integer> atLeast5 = x -> x > 5;

public interface Predicate<T> { boolean test(T t); }

Predicate T

boolean

Page 20: Java8 lambdas chapter1_2

Type Inference

• ラムダ式を使った型推論

• 後者では、型を指定していないため引数も戻り値の型も java.lang.Objectとして判別される -> 足し算ができないと怒られる

/* 正常に動く */ BinaryOperator<Long> addLongs = (x, y) -> x + y; /* コンパイルエラー */ BinaryOperator add = (x, y) -> x + y;

Page 21: Java8 lambdas chapter1_2

Key Points

• ラムダ式は、データであるかのように振る舞いを実装でき、メソッド名を省略できる

• ラムダ式は、以下のように書くことができる

• 関数型インターフェイスは定義されている抽象メソッドが1つだけあるインターフェイスのことで、ラムダ式は、関数型インターフェイスに対して適用することができる

BinaryOperator<Integer> add = (x, y) -> x + y;