Java 8のStream APIは簡潔なコードで複雑な処理を実現でき、開発効率を向上させる強力なツールです。以下に日常的に使用するユースケースを整理します。
一. データ変換処理
1. リスト間変換
データリスト = データリスト.stream().map(要素 -> {
新しいオブジェクト = new オブジェクト();
BeanUtils.copyProperties(要素, 新しいオブジェクト);
新しいオブジェクト.setプロパティ("値");
return 新しいオブジェクト;
}).collect(Collectors.toList());
2. 要素単位の更新
// 単純なプロパティ設定
データリスト.forEach(要素 -> 要素.setプロパティ("値"));
// 複数プロパティ同時更新
データリスト.forEach(要素 -> {
要素.setプロパティ("値");
要素.setプロパティ2("追加データ");
});
二. 集計処理
BigDecimal型の合計計算
public static void main(String[] args) {
List<請求データ> 請求明細 = Arrays.asList(
new 請求データ("I1001", BigDecimal.valueOf(9.99), BigDecimal.valueOf(1)),
new 請求データ("I1002", BigDecimal.valueOf(19.99), BigDecimal.valueOf(1.5))
);
BigDecimal 合計金額 = 請求明細.stream()
.map(x -> x.get数量().multiply(x.get単価()))
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(合計金額.setScale(2, RoundingMode.HALF_UP));
}
条件付きカウント
long 対象数 = リスト.stream().filter(s -> s.length() == 3).count();
三. 複雑なフィルタリング
Predicate<データオブジェクト> 表示条件 = 要素 -> {
boolean 表示フラグ = false;
BigDecimal スコア = 要素.getスコア();
BigDecimal 基準値 = 要素.get基準スコア();
String 調整理由 = 要素.get調整理由();
if (スコア != null) {
if (基準値 != null) {
表示フラグ = !(基準値.compareTo(スコア) == 0);
} else if (StringUtils.isNotEmpty(調整理由)) {
表示フラグ = true;
}
}
return 表示フラグ;
};
List<データオブジェクト> 対象リスト = データコレクション.get();
if (CollectionUtils.isNotEmpty(対象リスト)) {
List<データオブジェクト> 結果リスト = 対象リスト.stream()
.filter(表示条件)
.collect(Collectors.toList());
データコレクション.set(結果リスト);
}
四. リストからマップへの変換
@Data
public class 人物情報 {
private Integer 識別番号;
private String 名前;
private Integer 年齢;
}
List<人物情報> 人物リスト = Arrays.asList(
new 人物情報(1, "Jack", 3),
new 人物情報(2, "Mary", 4)
);
// キーと値のペア作成
Map<Integer,String> 簡易マップ = 人物リスト.stream()
.collect(Collectors.toMap(人物情報::get識別番号, 人物情報::getName));
// 重複キーを保持したグルーピング
Map<String, 人物情報> 重複マップ = 人物リスト.stream()
.collect(Collectors.toMap(
人物情報::getName,
a -> a,
(k1, k2) -> k1
));
// 年齢別グルーピング(順序保持)
LinkedHashMap<Integer, List<人物情報>> 年齢別マップ = 人物リスト.stream()
.collect(Collectors.groupingBy(
人物情報::get年齢,
LinkedHashMap::new,
Collectors.toList()
));
五. 存在確認処理
private boolean 6歳以上確認(List<人物情報> 人物リスト) {
Optional<人物情報> 存在意図 = 人物リスト.stream()
.filter(i -> i.get年齢() > 6)
.findAny();
return 存在意図.isPresent();
}
注:リスト→マップ変換は検索処理の効率化を目的とし、O(n)→O(1)の性能改善が期待できます。マップ内でのデータ変更は元のリストにも反映されることに注意が必要です。