#21 Javaで学ぶコレクション操作の応用(フィルタ・マップ的な考え方)の基本
はじめに
Javaで配列やリストを扱っていると、「条件に合うものだけ取り出したい」「中身を全部別の形に変換したい」という場面によく出会います。これまでfor文とif文を組み合わせて書いていた処理も、Java 8以降で使えるようになったStream APIを使うと驚くほどすっきり書けます。Stream APIとは、コレクションの要素を一列に並べて順番に処理する仕組みのことです。この記事では、コレクション操作の中でも特によく使う「フィルタ」と「マップ」という考え方を、初心者向けに丁寧に解説します。
フィルタとマップとは何か
まず言葉の意味を整理しましょう。「フィルタ(filter)」は、コレクションの中から条件に合う要素だけを選び出す操作です。「マップ(map)」は、コレクションの各要素を別の値に変換する操作です。どちらも「元のリストを直接いじらず、新しい結果を作る」という点が共通しています。この考え方は関数型プログラミング(処理を小さな関数の組み合わせとして表現するスタイル)由来のものです。Python(リスト内包表記)やJavaScript(Array.filter/map)にも似た機能があります。
従来のfor文との比較
たとえば「整数リストから偶数だけを取り出し、2倍にする」処理を、従来のfor文で書くとこうなります。
List<Integer> result = new ArrayList<>();
for (int n : numbers) {
if (n % 2 == 0) {
result.add(n * 2);
}
}
Stream APIを使うと、同じ処理が次のように書けます。
List<Integer> result = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.collect(Collectors.toList());
stream()でリストをストリーム(処理の流れ)に変換し、filterで条件を絞り込み、mapで値を変換し、最後にcollectで再びリストに戻す、という流れです。「何をしたいか」が処理の順番通りに読めるため、コードの意図がつかみやすくなるのが大きな利点です。
オブジェクトのリストにも応用できる
フィルタとマップは数値だけでなく、自作クラスのオブジェクトにも使えます。たとえば社員クラスEmployeeのリストから、30歳以上の社員の名前だけを取り出す例です。
List<String> names = employees.stream()
.filter(e -> e.getAge() >= 30)
.map(Employee::getName)
.collect(Collectors.toList());
Employee::getNameは「メソッド参照」と呼ばれる書き方で、e -> e.getName()と同じ意味を短く書けます。業務でCSVやデータベースから取得したデータを絞り込んで加工する場面など、実務でも頻出のパターンです。
つまずきやすいポイント
初心者がよく戸惑うのは、Streamは一度しか使えないという点です。collectなどで結果を取り出すと、そのストリームは「使用済み」になり、再度同じ変数に対して操作を呼ぶと例外(実行時エラー)が発生します。もう一度処理したい場合は、元のコレクションからstream()を呼び直す必要があります。また、filterやmapを呼んだだけでは実際の処理は実行されません。これは「遅延評価」と呼ばれる仕組みで、collectやforEachのような最終処理(終端操作)を呼んだ瞬間にまとめて計算が走ります。PythonやJavaScriptに慣れている人は、この「呼んだだけでは動かない」挙動に最初は戸惑うかもしれません。
まとめ
Stream APIのfilterとmapは、コレクションから必要なデータだけを取り出し、目的の形に変換するための強力な道具です。最初はfor文の方が書きやすく感じるかもしれませんが、慣れてくると「何を条件に絞り、どう変換するか」がコードにそのまま表れるため、読みやすさが大きく向上します。まずは身近なリストを使って、filterとmapを組み合わせる練習から始めてみてください。
関連記事
本ページはプロモーションを含みます。
参考書籍(PR)
Javaをもっと学びたい方には「スッキリわかるJava入門 第4版」がおすすめです。
PR
コードを書かずに自動化したい方へ
「学んだけど自分の作業に組み込む時間がない」という方向けに、ダブルクリックで動くWindows専用の自動化ツールをオーダーメイドで作成しています。気になる方はこちらをご覧ください。
コメント
コメントを投稿