
はじめに
Java の Stream API は、大量のデータを効率的に処理するための便利な機能を提供します。その中でも map メソッドは、各要素を別の型に変換する中間操作を簡潔に実現します。
本記事では、map メソッドの基本的な使い方から応用例までを、コード例を交えながら詳しく解説します。さらに、flatMap メソッドとの違いや使い分けについても学びます。
mapとは
map は Stream API の中間操作で、各要素を別の要素に変換するために使用されます。これにより、データを加工したり、新しい型に変換する処理が簡単に記述できます。例えば、以下のような用途があります。
基本的なmapの使用例
比較簡単な例から見ていきましょう。
文字列を大文字に変換
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");
// 大文字に変換
List<String> upperCaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println("Upper Case Names: " + upperCaseNames);
// 実行結果:
// [ALICE, BOB, CHARLIE]
}
}
数値を倍に変換
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
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("Doubled Numbers: " + doubledNumbers);
// 実行結果:
// [2, 4, 6, 8, 10]
}
}
mapの基本概念
map は Stream API のメソッドの一つで、Function (関数型インターフェース) を参照として受け取り、それを適用した要素で構成される Stream を返します。
Functionとは
Function は、たった1つの基本メソッド apply を持つ関数型インターフェースです。この apply メソッドは参数を受け、その参数に依存した返り値を返します。主にラムダ式の関数定義を通じて実装されます。以下は、Function の基本例です。
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
Function<Integer, String> intToString = n -> "Number: " + n;
System.out.println(intToString.apply(5));
// 実行結果:
// Number: 5
}
}
詳しくは、関数型インターフェースに関する記事を確認してみてください!
map で Function を利用する例
以下の例は、数値のリストの各要素の数値を倍に変換するものです。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// map で数値を倍に変換
List<Integer> doubledNumbers = numbers.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println("Doubled Numbers: " + doubledNumbers);
// 実行結果:
// Doubled Numbers: [2, 4, 6, 8, 10]
}
}
Functionを別作することで、同じ条件を複数の場所で再利用できる為、コードの再利用性を高めることができます。Functionを作らずとも、別メソッドを用意しそれを利用することもできます。
ラムダ式のメソッド参照を利用する例
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// メソッド参照を使用して数値を倍に変換
List<Integer> doubledNumbers = numbers.stream()
.map(MapExample::toDouble)
.collect(Collectors.toList());
System.out.println("Doubled Numbers: " + doubledNumbers);
}
// メソッド参照先
public static Integer toDouble(Integer number) {
return number * 2;
}
}

map と似た中間操作にflatMapというものがあります。参考までに、mapとflatMapの違いについて解説していきます。
mapとflatMapの違い
map と似た中間操作にflatMapというものがあります。これらの違いは、以下のとおりです。
| 操作 | 入力データ構造 | 出力データ構造 |
|---|---|---|
| map | Stream<T> | Stream<R> |
| flatMap | Stream<Stream<T>> | Stream<T> |

それぞれの使い方を例を使って解説します。
mapの例
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapVsFlatMap {
public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d"),
Arrays.asList("e", "f")
);
// map を使用
List<Stream<String>> mapped = listOfLists.stream()
.map(List::stream)
.collect(Collectors.toList());
System.out.println("Mapped: " + mapped);
// 実行結果:
// [java.util.stream.ReferencePipeline$Head@xxx, ...]
}
}

“a”, “b”のStream、 “c”, “d”のStream、”e”, “f”のStreamを格納しているList情報が出力されてます。多次元配列のイメージです。
flatMapの例
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapVsFlatMap {
public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d"),
Arrays.asList("e", "f")
);
// flatMap を使用
List<String> flattened = listOfLists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println("Flattened: " + flattened);
// 実行結果:
// [a, b, c, d, e, f]
}
}

mapでは多次元配列のようなものが返ってきていましたが、ここでは1つのList情報が出力されています。
flatMapの使い所:
以下は、文字列をスペースで分割して平坦化する例です。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapExample {
public static void main(String[] args) {
List<String> sentences = Arrays.asList(
"Hello World",
"Java Stream API",
"FlatMap Example"
);
// 各文字列をスペースで分割し、平坦化
List<String> words = sentences.stream()
.flatMap(sentence -> Arrays.stream(sentence.split(" ")))
.collect(Collectors.toList());
System.out.println("Words: " + words);
// 実行結果:
// [Hello, World, Java, Stream, API, FlatMap, Example]
}
}
まとめ
Stream API のこれらの操作を活用することで、より簡潔かつ効率的なデータ操作が可能になります。ぜひコードに取り入れてみてください!
