APIリファレンスを見ると、
ストリーム・パイプラインは順次、並列のいずれかで実行できます。この実行モードは、ストリームのプロパティの1つです。ストリームの作成時には、順次実行または並列実行の初期選択が行われます。(たとえば、Collection.stream()では順次ストリームが作成され、Collection.parallelStream()では並列ストリームが作成されます。)
Stream (Java Platform SE 8 )
と書いてあるけどよくわからないのでサンプルを書く。
今回の環境: Mac OS X Yosemite
$ uname -mrsv
Darwin 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64
$ java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
サンプルコード。数値のリストを順次処理と並列処理してみる。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Sample{
public static void main(String[] args){
test_stream();
test_parallelStream();
}
// 2乗の値を返す
private static int square(int x){
// 数値を標準出力へ
System.out.println("number: " + x);
return x * x;
}
private static void test_stream(){
final List<Integer> numbers =
Arrays.asList(1, 2, 3, 4, 5);
// 順次処理のストリームを生成
System.out.println("create stream");
Stream<Integer> squares =
numbers.stream()
.map(x -> square(x));
// 2乗した値を標準出力へ
System.out.println("output");
squares.forEach((s) -> System.out.println("square: " + s));
System.out.println();
}
private static void test_parallelStream(){
final List<Integer> numbers =
Arrays.asList(1, 2, 3, 4, 5);
// 並列処理のストリームを生成
System.out.println("create parallel stream");
Stream<Integer> squares =
numbers.parallelStream()
.map(x -> square(x));
// 2乗した値を標準出力へ
System.out.println("output");
squares.forEach((s) -> System.out.println("square: " + s));
System.out.println();
}
}
実行結果。並列処理のほうは、元の数値のリスト通りに処理されていないことがわかる (並列処理なので出力される順番はデタラメになる)。
$ java Sample
create stream
output
number: 1
square: 1
number: 2
square: 4
number: 3
square: 9
number: 4
square: 16
number: 5
square: 25
create parallel stream
output
number: 3
square: 9
number: 5
square: 25
number: 2
square: 4
number: 4
square: 16
number: 1
square: 1
もうひとつわかることは、順次処理でも並列処理でも、 map メソッドに指定された関数 (ここでは square メソッド) をすぐには処理をしていないこと。
必要になってから実行をするという、遅延評価がここで使われている (ここでは Stream.forEach() メソッドをコールしたときに square の処理が実行されている)。
-
ref.
- Collection (Java Platform SE 8 )
- Stream (Java Platform SE 8 )
- Java による関数型プログラミング Java 8 ラムダ式と Stream ← 参考書籍
tags: java
Posted by NI-Lab. (@nilab)