Java 逆引き集 | Stream API の基本(stream(), filter, map, collect) — データ変換

Java Java
スポンサーリンク

Stream API の基本(stream(), filter, map, collect) — データ変換

Java 8 以降で導入された Stream API は「コレクションを宣言的に処理する」ための強力な仕組みです。
初心者がつまずきやすいポイントを、基本操作(stream → filter → map → collect) に絞って、例題とテンプレートで整理します。


基本の流れ

  1. stream()
    • コレクションからストリームを生成。
    • 例: list.stream()
  2. filter(Predicate)
    • 条件に合う要素だけ残す。
    • 例: .filter(x -> x > 10)
  3. map(Function)
    • 要素を変換する。
    • 例: .map(String::length)
  4. collect(Collector)
    • 結果をリストやセットなどにまとめる。
    • 例: .collect(Collectors.toList())

基本コード例

1) 数値リストから偶数だけ取り出す

import java.util.*;
import java.util.stream.*;

public class StreamBasic {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1,2,3,4,5,6,7,8,9,10);

        List<Integer> evens = nums.stream()
                                  .filter(n -> n % 2 == 0)
                                  .collect(Collectors.toList());

        System.out.println(evens); // [2, 4, 6, 8, 10]
    }
}
Java

2) 文字列リストを大文字に変換

List<String> words = List.of("java", "stream", "api");

List<String> upper = words.stream()
                          .map(String::toUpperCase)
                          .collect(Collectors.toList());

System.out.println(upper); // [JAVA, STREAM, API]
Java

3) オブジェクトから特定フィールドを抽出

class User {
    String name; int age;
    User(String n, int a) { name=n; age=a; }
}

List<User> users = List.of(new User("Alice",20), new User("Bob",30));

List<String> names = users.stream()
                          .map(u -> u.name)
                          .collect(Collectors.toList());

System.out.println(names); // [Alice, Bob]
Java

例題で理解する

例題1: 成績リストから「合格者の名前」だけ抽出

class Student {
    String name; int score;
    Student(String n, int s) { name=n; score=s; }
}

List<Student> list = List.of(
    new Student("Tanaka", 80),
    new Student("Sato", 55),
    new Student("Ito", 90)
);

List<String> passed = list.stream()
                          .filter(s -> s.score >= 60)
                          .map(s -> s.name)
                          .collect(Collectors.toList());

System.out.println(passed); // [Tanaka, Ito]
Java
  • ポイント: filter で条件抽出 → map でフィールド変換 → collect でリスト化。

例題2: 商品価格から「税込価格リスト」を作る

List<Integer> prices = List.of(100, 200, 300);

List<Integer> withTax = prices.stream()
                              .map(p -> (int)(p * 1.1))
                              .collect(Collectors.toList());

System.out.println(withTax); // [110, 220, 330]
Java
  • ポイント: map で計算処理を適用。

例題3: 文字列リストから「長さが3以上」のものを抽出

List<String> words = List.of("a","bb","ccc","dddd");

List<String> longWords = words.stream()
                              .filter(w -> w.length() >= 3)
                              .collect(Collectors.toList());

System.out.println(longWords); // [ccc, dddd]
Java

テンプレート集

  • 基本形
list.stream()
    .filter(x -> 条件)
    .map(x -> 変換)
    .collect(Collectors.toList());
Java
  • フィールド抽出
objects.stream()
       .map(o -> o.field)
       .collect(Collectors.toList());
Java
  • 条件付き抽出
list.stream()
    .filter(x -> x > threshold)
    .collect(Collectors.toList());
Java
  • 変換+集計
int sum = list.stream()
              .mapToInt(x -> x.value)
              .sum();
Java

落とし穴と回避策

  • 終端操作を忘れる: Stream は「collect」「forEach」など終端操作を呼ばないと実行されない。
  • 副作用に頼りすぎ: map/filter 内で外部変数を書き換えるのは避ける。結果は collect でまとめる。
  • 無限ストリームの有限化忘れ: Stream.generateiterate は limit/takeWhile を必ず入れる。
  • sorted/distinct は全件読み込み: 大量データではメモリ負荷に注意。

まとめ

  • stream() → filter → map → collect が基本パターン。
  • filter は「選別」、map は「変換」、collect は「まとめ」。
  • 宣言的に書けるので、コードが短く読みやすくなる。
  • 実務では「条件抽出+フィールド変換+リスト化」が最もよく使われる組み合わせ。

👉 練習課題: 「社員リストから年齢30以上の人の名前を大文字にしてリスト化」してみると、filter・map・collect の流れが自然に身につきます。

タイトルとURLをコピーしました