0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

StreamAPIのmap関数についての理解

Last updated at Posted at 2025-06-16

【Java】StreamAPIのmap()メソッドを完全理解!初心者向け徹底解説

はじめに

JavaのStreamAPIは、コレクションの操作を直感的かつ効率的に行える強力な機能です。その中でもmap()メソッドは最も頻繁に使用される操作の一つです。

この記事では、map()メソッドの基本的な使い方から実践的な活用例まで、初心者にもわかりやすく解説していきます。

map()メソッドとは?

map()メソッドは、ストリームの各要素に対して指定した変換処理を適用し、新しいストリームを生成するメソッドです。

簡単に言うと:

  • 元のデータを別の形に変換したい時に使用
  • 一対一の変換処理(1つの入力に対して1つの出力)
  • 元のストリームは変更されず、新しいストリームが作成される

基本的な構文

Stream<R> map(Function<? super T, ? extends R> mapper)
  • T: 入力の型
  • R: 出力の型
  • mapper: 変換処理を定義する関数

実際のコード例で理解しよう

例1: 文字列を大文字に変換

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MapExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("alice", "bob", "charlie");
        
        // 従来の書き方(for文)
        List<String> upperNamesOld = new ArrayList<>();
        for (String name : names) {
            upperNamesOld.add(name.toUpperCase());
        }
        
        // Stream APIのmap()を使用
        List<String> upperNames = names.stream()
            .map(String::toUpperCase)
            .collect(Collectors.toList());
        
        System.out.println(upperNames); // [ALICE, BOB, CHARLIE]
    }
}

例2: 数値を2倍にする

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

List<Integer> doubledNumbers = numbers.stream()
    .map(n -> n * 2)
    .collect(Collectors.toList());

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

例3: オブジェクトのプロパティを取得

class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String getName() { return name; }
    public int getAge() { return age; }
}

public class PersonExample {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("田中", 25),
            new Person("佐藤", 30),
            new Person("鈴木", 35)
        );
        
        // 名前だけを取得
        List<String> names = people.stream()
            .map(Person::getName)
            .collect(Collectors.toList());
        
        // 年齢だけを取得
        List<Integer> ages = people.stream()
            .map(Person::getAge)
            .collect(Collectors.toList());
        
        System.out.println(names); // [田中, 佐藤, 鈴木]
        System.out.println(ages);  // [25, 30, 35]
    }
}

ラムダ式とメソッド参照の使い分け

ラムダ式の場合

// 複雑な変換処理
List<String> formattedNames = people.stream()
    .map(person -> person.getName() + "さん(" + person.getAge() + "歳)")
    .collect(Collectors.toList());

メソッド参照の場合

// シンプルな変換処理
List<String> names = people.stream()
    .map(Person::getName)  // メソッド参照の方がスッキリ
    .collect(Collectors.toList());

実践的な活用例

例1: CSVデータの変換

List<String> csvLines = Arrays.asList(
    "田中,25,東京",
    "佐藤,30,大阪",
    "鈴木,35,名古屋"
);

List<Person> people = csvLines.stream()
    .map(line -> {
        String[] parts = line.split(",");
        return new Person(parts[0], Integer.parseInt(parts[1]));
    })
    .collect(Collectors.toList());

例2: APIレスポンスの変換

class ApiResponse {
    private String id;
    private String title;
    private boolean active;
    
    // コンストラクタ、ゲッター等省略
}

class DisplayItem {
    private String displayTitle;
    private String status;
    
    public DisplayItem(String title, boolean active) {
        this.displayTitle = title.toUpperCase();
        this.status = active ? "有効" : "無効";
    }
    
    // ゲッター等省略
}

// APIレスポンスを表示用オブジェクトに変換
List<ApiResponse> responses = getApiResponses();
List<DisplayItem> displayItems = responses.stream()
    .map(response -> new DisplayItem(response.getTitle(), response.isActive()))
    .collect(Collectors.toList());

map()と他のStream操作の組み合わせ

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

List<String> result = numbers.stream()
    .filter(n -> n % 2 == 0)        // 偶数のみフィルタ
    .map(n -> n * n)                // 二乗
    .map(n -> "数値: " + n)         // 文字列に変換
    .collect(Collectors.toList());

System.out.println(result); // [数値: 4, 数値: 16, 数値: 36, 数値: 64, 数値: 100]

よくある間違いとその対処法

間違い1: nullチェックを忘れる

// 危険な例
List<String> names = people.stream()
    .map(Person::getName)  // nameがnullの場合NullPointerException
    .collect(Collectors.toList());

// 安全な例
List<String> names = people.stream()
    .map(person -> person.getName() != null ? person.getName() : "名前なし")
    .collect(Collectors.toList());

// Optional使用例
List<String> names = people.stream()
    .map(Person::getName)
    .map(name -> Optional.ofNullable(name).orElse("名前なし"))
    .collect(Collectors.toList());

間違い2: mapとflatMapの使い分け

// mapの場合(一対一変換)
List<String> words = Arrays.asList("hello", "world");
List<Integer> lengths = words.stream()
    .map(String::length)  // 各文字列の長さを取得
    .collect(Collectors.toList());

// flatMapの場合(一対多変換)
List<String> sentences = Arrays.asList("hello world", "java stream");
List<String> allWords = sentences.stream()
    .flatMap(sentence -> Arrays.stream(sentence.split(" ")))
    .collect(Collectors.toList());

パフォーマンスの考慮事項

1. 並列処理の活用

// 大量のデータを処理する場合
List<Integer> largeList = IntStream.range(1, 1000000)
    .boxed()
    .collect(Collectors.toList());

List<Integer> result = largeList.parallelStream()  // 並列処理
    .map(n -> n * n)
    .collect(Collectors.toList());

2. 中間操作の最適化

// 効率的な書き方
List<String> result = people.stream()
    .filter(person -> person.getAge() >= 20)  // filterを先に
    .map(Person::getName)                     // mapは後に
    .collect(Collectors.toList());

まとめ

map()メソッドは以下のような特徴があります:

  • 一対一変換: 1つの入力に対して1つの出力
  • 型変換可能: 異なる型に変換できる
  • 関数型: ラムダ式やメソッド参照が使用可能
  • 遅延評価: 終端操作が呼ばれるまで実行されない

使用する場面

  • データの形式を変換したい時
  • オブジェクトのプロパティを抽出したい時
  • 計算結果を新しいリストにしたい時

注意点

  • nullチェックを忘れずに
  • flatMapとの使い分けを理解する
  • パフォーマンスを考慮した書き方を心がける

Stream APIのmap()メソッドをマスターすることで、より読みやすく保守性の高いJavaコードが書けるようになります。まずは簡単な例から始めて、徐々に複雑な処理にチャレンジしてみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?