StreamAPIの基本

#はじめに
・StreamAPIの代表的なメソッドと、基本的なコーディング例を示します。
・StreamAPIの考え方や応用例、テクニックについては他のエントリーへ委譲し、ここではできるだけシンプルに書くように努めます。
・Streamはラムダ式またはメソッド参照を与えて書くのが一般的ですが、あえて関数型インタフェースを宣言します。


#StreamAPIとは
・SE8で追加された、データの集合を扱うためのAPI。主な目的は並列処理への対応。StreamAPIを用いると、順次処理から並行処理への切替えが容易になる。

・java.util.streamパッケージ配下のインタフェースのことであり、java.ioパッケージで用いるストリームとは別物。

・java.util.streamパッケージは、BaseStreamインタフェースを基底として、参照型を扱うためのStreamインタフェースと、プリミティブ型を扱うための3つのインタフェースにより構成される。

・StreamはListやMapなどのデータ集合をもとに生成し、0回以上の中間操作と、1回の終端操作を実行することで結果を得る。


###より詳しく
[Java(tm) Platform Standard Edition 8 パッケージ java.util.stream](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/package-summary.html)
[Java Stream APIをいまさら入門 - 基本編](http://qiita.com/potsunen/items/369dd3fcb9ccb8fcfa44)
[Java8 Streamざっくりまとめ](http://qiita.com/frost_star/items/fb87caf05e106c46dfe4)


#生成
####参照型Stream

```java
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream();
```

####プリミティブ型Stream

```java
IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
```

####配列から

```java
int[] array = { 1, 2, 3, 4, 5 };
IntStream intStream = Arrays.stream(array);
```

####レンジを指定して

```java
IntStream intStream = IntStream.range(1, 5);
```

####ファイルから

```java
Path path = Paths.get("D:\\hoge.txt");
Stream<String> fileStream = Files.lines(path)
```        

###最も単純なStream操作

```java
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream();
stream.forEach(System.out::println);
```

Integer型のStreamを生成し、中間操作0回、終端操作1回で、標準出力処理を実行する。
forEachは終端操作。終端操作については後述。
基本的には、これに任意の回数の様々な中間操作と、同じく様々な終端操作のうちいずれか1回を組み合わせて利用する。

###より詳しく

[Java 8 Stream API にテキストを流してみる（生成編）](http://qiita.com/kumazo/items/0876c5b251ecc131c960)

#中間操作
####フィルタリング

```java
Stream<String> stream = Stream.of("A", "B", "A", "B", "B", "A");
Predicate<String> isA = "A"::equals;
stream.filter(isA).forEach(System.out::println);
```

Predicate型のisHogeHogeを間に掛けてFalseを間引くイメージ。
Predicate<T>は関数型インタフェース。
関数型インタフェースについては以下。
[３分でわかる基本の関数型インタフェース](http://qiita.com/Takmiy/items/2a43dbc5ca09017b831e)

####マッピング
```java
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Function<Integer, Integer> toDouble = param -> param * 2;
stream.map(toDouble).forEach(System.out::println);
```
Streamの各要素をキーとして、対応する値のStreamを返す。
要は変換処理みたいなもの。
サンプルはわかりやすくFunctionを使ったが、この場合はUnaryOperatorがスマート。
ラムダ式については以下。
[Java8 Lambdaの文法拡張まとめ](http://d.hatena.ne.jp/nowokay/20130824)
[インタフェースの実装がラムダになるまで](http://qiita.com/Takmiy/items/21e9aa675bec0dfea31b)

####ソート
```java
Stream<Integer> stream = Stream.of(3, 2, 1, 5, 4);
Comparator<Integer> comparator = Comparator.reverseOrder();
stream.sorted(comparator).forEach(System.out::println);
```

sortedにcomparatorを与えることで、順序を指定する。
Comparatorについては以下。
[(o1, o2) -> o1 - o2 なんて呪文はもうやめて！ - Java8でのComparatorの使い方](http://qiita.com/tag1216/items/50ecf6a7bc10218ee889)


#終端操作
####マッチング
```java
Stream<String> stream = Stream.of("George", "John", "Ringo", "Paul");
Predicate<String> isRingo = "Ringo"::equals;
boolean isMatch = stream.anyMatch(isRingo);
```
allMatch、noneMatchなどのバリエーションもある。

####カウント
```java
Stream<String> countSt = Stream.of("George", "John", "Ringo", "Paul");
long result = countSt.count();
```

####リダクション
```java
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream();
BinaryOperator<Integer> sum = Integer::sum;
Optional<Integer> result = stream.reduce(sum);
```
畳み込みなど、結果を単一の値へ処理する。
戻り値はOptional。Optionalについては以下。
[Java 8 "Optional" ～ これからのnullとの付き合い方 ～](http://qiita.com/shindooo/items/815d651a72f568112910)

####可変リダクション
```java
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = list.stream();
List<Integer> resultList = stream.collect(Collectors.toCollection(ArrayList::new));
resultList.forEach(System.out::print);
```
ArrayListなど、集合へ処理する。

###より詳しく
[Java 8 Stream API にテキストを流してみた（終端操作編）](http://qiita.com/kumazo/items/284098c530fceb05805c)
[Java8 Streamのリダクション操作について](http://qiita.com/frost_star/items/a36e66dff419e7c07151)


#並列処理
```java
Stream<String> stream= Stream.of("A", "B", "C", "D", "E", "F");
stream.parallel().forEach(param -> System.out.println(param + " thread-id: " + Thread.currentThread().getId()));
```

生成時にpararelStream()を使うか、中間操作でparallel()を噛ませるだけで並列処理になる。

###より詳しく
[さあ、並列プログラミングをはじめよう](http://qiita.com/koduki/items/086d42b5a3c74ed8b59e)
[Java8のStreamとParallelStreamの使い分けについて](http://qiita.com/clomie/items/07bac6b31314486f1591)
[streamとparallelStreamについての考察](https://togetter.com/li/638124)
[Java それぞれ書き方でどれほどパフォーマンスが違うのか？計測比較してみた。Streamとループとか](http://qiita.com/ota-meshi/items/40d5dcb0e99574a8a368)

並列処理は書ききれないので深くは触れません。