14. Javaはどこへ向かうのか
Copyright 2015 FUJITSU LIMITED
It is my belief that the best direction for evolving Java
is to encourage a more functional style of
programming. The role of Lambda is primarily to
support the development and consumption of more
functional-like libraries; I've offered examples such as
filter-map-reduce to illustrate this direction.
Simply put, we believe the best thing we can do for Java
developers is to give them a gentle push towards a more
functional style of programming. We're not going to
turn Java into Haskell, nor even into Scala.
http://mail.openjdk.java.net/pipermail/lambda-dev/2011-August/003877.html
Brian Goetz
13
28. ループから再帰
Copyright 2015 FUJITSU LIMITED
int foo(Bar[] bars) {
int result = 0;
for (int i = 0 ; i < bars.length ; ++i)
result += bars[i].get();
return result;
}
int foo(final Bar[] bars) {
return foo1(0, 0, bars);
}
int foo1(final int n, final int result, final Bar[] bars) {
if (n == bars.length)
return result;
return foo1(n+1, bars[n].get()+result, bars);
}
ループ
再帰
再代入の解消
27
29. 末尾再帰最適化(TCO)
Copyright 2015 FUJITSU LIMITED
Java(JIT)では未対応
最後の処理が自分自身への呼び出しなら、
関数コール(新しいスタック作成)しない。
ループ処理のように同じスタックで処理する。
int foo1(final int n, final int result, final Bar[] bars) {
if (n == bars.length)
return result;
return foo1(n+1, bars[n].get()+result, bars);
}
最後の処理が
自分自身への
呼び出し
28
32. ループからストリーム
Copyright 2015 FUJITSU LIMITED
Java SE 7の
糖衣構文
int foo(Bar[] bars) {
int result = 0;
for (int i = 0 ; i < bars.length ; ++i)
result += bars[i].get();
int foo(Bar[] bars) {
int result = 0;
for (Bar b : bars)
result += b.get();
int foo(Bar[] bars) {
return Arrays.stream(bars)
.mapToInt( b -> b.get() );
.sum();
Java SE 8の
stream API
31
33. ループv.s.ストリーム(並列化)
Copyright 2015 FUJITSU LIMITED
int foo(Bar[] bars) throws InterruptedException {
BarSum[] barSum = new BarSum[N];
for (int i = 0 ; i < N ; ++i)
barSum[i] = new BarSum(bars, bars.length/N*i,
bars.length/N*(i+1));
int result = 0;
for (int i = 0 ; i < N ; ++i) {
barSum[i].join();
result += barSum[i].result;
}
return result;
}
class BarSum extends Thread {
Bar[] bars;
int begin, end;
int result;
BarSum(Bar[] bars, int begin, int end) {
this.bars = bars;
this.begin = begin;
this.end = end;
}
public void run() {
for (int i = begin ; i < end ; ++i)
result += bars[i].get();
}
}
ループの並列化
int foo(Bar[] bars) {
return Arrays.stream(bars)
.parallel()
.mapToInt( b -> b.get() );
.sum();
ストリームの並列化
32
39. 多段ループ処理
Copyright 2015 FUJITSU LIMITED
int foo(List<Integer> list) {
ArrayList<Integer> list2 = new ArrayList<>;
for (int i : list)
if (i > 30) list2.add(i);
ArrayList<Integer> list3 = new ArrayList<>;
for (int i : list2) list3.add(i * 2)
int result = 0; int count = 0;
for (int i : list3) {
result += i;
count ++;
if (count == 50)
break;
}
return result;
待ち合わせ
待ち合わせ
38
41. ループの並列処理化
Copyright 2015 FUJITSU LIMITED
int foo(List<Integer> list) {
int result = 0;
int count = 0;
for (int i : list) {
if (i > 30) {
result += i *2;
count ++;
if (count == 50)
break;
}
}
return result;
}
複数スレッドで
同期を取りながら
50数える必要がある
ループは一つになったが
並列化するには、
40