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
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
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
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
{ 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
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
result = 0; int count = 0; for (int i : list) { if (i > 30) { result += i *2; count ++; if (count == 50) break; } } return result; } 複数スレッドで 同期を取りながら 50数える必要がある ループは一つになったが 並列化するには、 40