1. 導入
実務におけるJava開発では、データベースから取得した大量のリストをフィルタリングしたり、並び替えたりする処理が頻繁に発生します。for文やif文を多用するとコードが冗長になり、可読性が低下しがちです。Java 8から導入されたStream APIを活用することで、宣言的かつ簡潔にデータ加工を記述でき、バグの混入リスクを最小限に抑えることが可能です。今回は、現場で特によく使う中間操作メソッドに焦点を当てて解説します。
2. 基礎知識
Stream APIの中間操作は、結果を確定させず「処理のパイプライン」を構築するものです。
distinct(): 重複を除去します。
sorted(): 要素を自然順序または指定した比較子で並び替えます。
peek(): 各要素に対して処理を行い、そのままストリームを流します。デバッグに有用です。
limit(n): 先頭からn要素のみを抽出します。
skip(n): 先頭からn要素を読み飛ばします。
takeWhile(predicate): 条件が偽になるまで要素を抽出します。
dropWhile(predicate): 条件が偽になるまで要素を読み飛ばします。
3. 実装/解決策
これらのメソッドを組み合わせる際は、「状態を持つ操作(sortedやdistinct)」はコストが高いという点に留意する必要があります。特に、大量のデータを扱う際は、可能な限り絞り込んでから高コストな操作を行うのが鉄則です。例えば、リストをソートする前にlimitで件数を絞る、といった工夫がメモリ効率の向上に繋がります。
4. サンプルプログラム
以下のコードは、数値リストから重複を除き、ソートし、特定の条件でフィルタリングしてログ出力する例です。
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List
List
// 重複を除去
.distinct()
// 昇順にソート
.sorted()
// 処理過程を確認(デバッグ用)
.peek(n -> System.out.println("処理中の値: " + n))
// 5未満をスキップ
.dropWhile(n -> n < 5)
// 8以下までを取り出す
.takeWhile(n -> n <= 8)
.collect(Collectors.toList());
System.out.println("最終結果: " + result);
}
}
5. 応用・注意点
現場で陥りやすい罠として、peek()の誤用があります。peek()はあくまで「中間操作」であるため、終端操作(collect()やforEach()など)が実行されない限り、peek内の処理は一切動きません。また、takeWhile/dropWhileはJava 9以降の機能ですが、順序付きストリーム(Listなど)では非常に強力です。ただし、並列ストリーム(parallelStream)で使用する場合、順序の保証が難しくなるため、データの一貫性が求められる業務ロジックでは注意深く使用してください。最新のJava環境であれば、Sequenced Collections(Listのfirst/last取得など)と組み合わせることで、さらに柔軟なデータ操作が可能になります。

コメント