8. 中間操作
Javaの**中間操作(Intermediate Operations)**は、ストリームを加工して「新しいストリームを返す」メソッドです。終端操作が呼ばれるまで実行されない(Lazy)という性質を持っています。
主要な中間操作のすべてを網羅したサンプルコードを紹介します。
中間操作の全主要メソッド・サンプル¶
Java
import java.util.*;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "cherry", "apple", "apricot", "elderberry");
// 1. filter : 条件に合うものを抽出
List<String> filtered = list.stream()
.filter(s -> s.startsWith("a"))
.collect(Collectors.toList()); // [apple, apple, apricot]
// 2. map : 各要素を別の値に変換
List<Integer> mapped = list.stream()
.map(String::length)
.collect(Collectors.toList()); // [5, 6, 6, 5, 7, 10]
// 3. distinct : 重複を取り除く
List<String> distincted = list.stream()
.distinct()
.collect(Collectors.toList()); // [apple, banana, cherry, apricot, elderberry]
// 4. sorted : 並び替える
List<String> sorted = list.stream()
.sorted()
.collect(Collectors.toList()); // 辞書順
// 5. limit : 先頭から指定した数だけ取り出す
List<String> limited = list.stream()
.limit(3)
.collect(Collectors.toList()); // [apple, banana, cherry]
// 6. skip : 先頭から指定した数だけ飛ばす
List<String> skipped = list.stream()
.skip(2)
.collect(Collectors.toList()); // [cherry, apple, apricot, elderberry]
// 7. peek : 各要素に処理を行い、そのまま次に流す(主にデバッグ用)
List<String> peeked = list.stream()
.peek(s -> System.out.println("Processing: " + s))
.filter(s -> s.length() > 5)
.collect(Collectors.toList());
// 8. flatMap : 1つの要素を複数の要素に展開して平坦化する
List<List<String>> complexList = Arrays.asList(
Arrays.asList("A", "B"),
Arrays.asList("C", "D")
);
List<String> flattened = complexList.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList()); // [A, B, C, D]
}
}
中間操作の分類と役割¶
中間操作は「状態を持つかどうか」で大きく2種類に分けられます。
ステートレス(Stateless)な操作¶
前の要素が何だったかに関係なく、その瞬間の要素だけで処理が決まる操作です。
filter: フィルタリングmap: マッピング(変換)flatMap: 平坦化peek: 覗き見
ステートフル(Stateful)な操作¶
全ての要素を一度確認しないと結果が出せない操作です。
distinct: 重複を消すために、過去に出た要素を記憶しておく必要があるsorted: 全部揃わないと並び替えができない- **
limit/skip**: 何番目かをカウントしておく必要がある
中間操作の英語名と覚え方¶
| メソッド | 英語での意味合い | イメージ |
|---|---|---|
filter |
選別する | ふるいにかける |
map |
対応付ける | 形を変える |
distinct |
個別の、重複のない | コピーを捨てる |
sorted |
整理された | 順番に並べる |
peek |
ちらっと見る | 通過時にメモを取る |
flatMap |
平らにする | ネスト(入れ子)を壊す |
まとめ:中間操作を繋げる(パイプライン)¶
中間操作の醍醐味は、これらを**数珠つなぎ(Method Chaining)**にできることです。
Java
List<String> finalResult = list.stream()
.distinct() // 重複を消して
.filter(s -> s.length() > 5) // 5文字より長いものを選び
.map(String::toUpperCase) // 大文字にして
.sorted() // 並び替える
.collect(Collectors.toList()); // 最後に箱に入れる
一番複雑で分かりにくいと言われるのは flatMap ですが、これの具体的な使い道の例を見てみますか?