「この処理、もっとスマートに書けないの?」と感じたことはありませんか?
Javaでfor文をぐるぐる書いて、「もっと簡潔にできないかな」と思った経験はありませんか?
例えば、リストから特定条件のデータだけを抽出したり、データを変換して別の形式にしたりといった処理。
そんなときに役立つのが Stream API です。
特にSpring Bootの開発現場では、データベースの検索結果やDTOの整形処理など、Stream APIが非常に役立ちます。
この記事では、初心者〜中級者向けに、Stream APIの基本から、よく使う処理、業務でありがちな落とし穴まで丁寧に解説していきます。
Stream APIの基本と実践的な使い方
Stream APIとは?
Java 8で導入されたStream APIは、コレクション操作を宣言的に書ける仕組みです。
従来の命令型スタイルとは異なり、何をしたいかを簡潔に表現できます。
List<String> names = Arrays.asList("Taro", "Jiro", "Hanako");
List<String> filtered = names.stream()
.filter(name -> name.startsWith("T"))
.collect(Collectors.toList());
System.out.println(filtered); // → [Taro]
よく使うStream操作まとめ(リスト形式)
-
.filter():条件で絞り込み(例:name -> name.length() > 3)
-
.map():要素の変換(例:name -> name.toUpperCase())
-
.collect():結果をリストなどに収集(例:Collectors.toList())
-
.sorted():並び替え(例:Comparator.naturalOrder())
-
.distinct():重複排除
-
.count():件数をカウント
Spring BootでのStream API活用例(DTO整形)
Spring Bootでは、Entity → DTO変換によく使われます。
List<User> users = userRepository.findAll();
List<UserDto> dtos = users.stream()
.map(user -> new UserDto(user.getId(), user.getName()))
.collect(Collectors.toList());
UserDtoの例:
public class UserDto {
private Long id;
private String name;
public UserDto(Long id, String name) {
this.id = id;
this.name = name;
}
}
つまずきやすいポイントと改善のコツ
ありがちなつまずき1:nullを含むリストに注意!
List<String> list = Arrays.asList("a", null, "b");
List<String> result = list.stream()
.filter(s -> s.length() > 0) // ← NullPointerException
.collect(Collectors.toList());
解決法:
.filter(Objects::nonNull)
または
.filter(s -> s != null && s.length() > 0)
ありがちなつまずき2:副作用(print, ログ)をmapでやらない
.map(user -> {
System.out.println(user.getName()); // ← mapで副作用NG
return user.getName();
})
正しいやり方:
.peek(user -> System.out.println(user.getName())) // peekは副作用OK
.map(User::getName)
書き換え例:before / after
Before(for文):
List<String> result = new ArrayList<>();
for (String s : names) {
if (s.startsWith("T")) {
result.add(s.toUpperCase());
}
}
After(Stream API):
List<String> result = names.stream()
.filter(s -> s.startsWith("T"))
.map(String::toUpperCase)
.collect(Collectors.toList());
コード量が減り、読みやすくなります。
まとめと次のステップ
まとめ
-
Stream APIは、コレクション操作を簡潔に記述できるJavaの機能。
-
Spring BootではDTO変換やデータ整形によく登場。
-
filter, map, collect などの基本操作を使いこなそう。
-
nullや副作用には注意が必要。
-
for文からStreamへの書き換えで、コードの可読性が大幅アップ!
【外部リンク】
Spring Framework公式ガイド – Spring MVC
【内部リンク】
Spring Bootのよく使われるアノテーションとは?初心者必見の解説と活用法