5. Java SE 8の超重要情報
Java SE 8 ローンチイベントの動画
徹底解説!Project Lambdaのすべて リターンズ
(@bitter_foxさん)
https://www.youtube.com/watch?v=gAMYhTl7t70
from old Java to modern Java - reloaded
(@cero_tさん)
https://www.youtube.com/watch?v=aLRonTjIeFI
Web記事
詳解 Java SE 8(@skrbさん)
http://itpro.nikkeibp.co.jp/article/COLUMN/20140212/536246/
書籍
Java SE 8実践プログラミング(以下「実践本」)
Javaによる関数型プログラミング(以下「関数本」)
Javaエンジニア養成読本(以下「養成本」)
5
13. 無名クラス
13
interface Calculator {
int calc(int a, int b);
}
Calculator c = new Calculator() {
public int calc(int a, int b) {
return a + b;
}
};
int result = c.calc(1, 2);
無名クラス
15. 推論による省略
15
interface Calculator {
int calc(int a, int b);
}
Calculator c = new Calculator() {
public int calc(int a, int b) {
return a + b;
}
};
int result = c.calc(1, 2);
左辺から推論可能
抽象メソッドが1つのみ
(=関数型インターフェイス)
ならば推論可能
17. 更なる省略
17
interface Calculator {
int calc(int a, int b);
}
Calculator c = (a, b) -> a + b;
int result = c.calc(1, 2);
メソッド本文が1文のみならば、return、{}、; が
省略可能
戻り値の有無によらない
引数が1つの場合、() が省略可能
引数無しの場合は省略不可
18. メソッドの引数にラムダ式を指定
18
interface Calculator {
int calc(int a, int b);
}
void print(int n1, int n2, Calculator c) {
System.out.println(“result = ” + c.calc(n1, n2))
}
print(1, 2, (a, b) -> a + b);
ラムダ式をメソッドの引数に渡すことも可能
引数の型から推論する
19. ジェネリクスに関する型推論強化
19
List<String> list = new ArrayList<>();
list.add("hoge");
list.addAll(Arrays.asList());
Arrays.asList(T… a)の戻り値はList<T>
Tは通常、asList()の引数の型から推論する
addAll()の引数はCollection<? extends String>
コンパイラが「T=String」と推論してくれる
Java SE 7だとコンパイルエラー
(Tに関する情報が無いので、T=Objectと推論される)
20. ジェネリクスに関する型推論強化
20
interface Function<T, R> {
R apply(T t);
}
void print(A a, Function<A, B> func) {
B b = func.apply(a);
System.out.println(b)
}
print("hoge", str -> str.length()); // 「4」と表示
ラムダ式の戻り値から推論
B = IntegerA = String
30. ポイント⑤ 汎用関数型インターフェイス
BiFunction<T, U, R>は、
TとUを引数とし、Rを戻り値とするメソッドを持つ
関数型インターフェイス
30
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}
※本当はもう1つデフォルトメソッドがありますが、省略しています
32. 汎用関数型インターフェイス一覧
32
関数型インターフェイス メソッド
Runnable void run()
Supplier<T> T get()
Consumer<T> void accept(T t)
BiConsumer<T, U> void accept(T t, U u)
Function<T, R> R apply(T t)
BiFunction<T, U, R> R apply(T t, U u)
UnaryOperator<T> T apply(T t)
BinaryOperator<T> T apply(T t1, T t2)
Predicate<T> boolean test(T t)
BiPredicate<T, U> boolean test(T t, U u)
※Runnable以外は、すべてjava.util.functionパッケージ
33. 基本データ型用の関数型インターフェイス
33
関数型インターフェイス メソッド
BooleanSupplier boolean getAsBoolean()
P Supplier p getAsP ()
P Consumer void accept(p p)
ObjP Consumer<T> void accept(T t, p p)
P Function<T> T apply(p p)
P ToQ Function q applyAsQ (p p)
ToP Function<T> p applyAsP (T t)
ToP BiFunction<T, U> p applyAsP (T t, U u)
P UnaryOperator p applyAsP (p p)
P BinaryOperator p applyAsP (p p1, p p2)
P Predicate boolean test(p p)
※「実践本」より抜粋
※p とq は、int、long、double。P とQ は、Int、Long、Double
34. ポイント⑥ ソースコードを読む
ラムダ式を引数に取るメソッドのソースコードを
読んで、どのように実行されているかを見る
34
default V compute(K key, Function<K, V> remappingFunction) {
V oldValue = get(key);
V newValue = remappingFunction.apply(key, oldValue);
put(key, newValue);
return newValue;
}
Map#compute()のソース(単純化しています)
Map<String, Integer> map = new HashMap<>();
・・・
int value = map.compute(“apple”, (k, v) -> v + 10);