Java Streamによる実務応用ケース

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)の性能改善が期待できます。マップ内でのデータ変更は元のリストにも反映されることに注意が必要です。

タグ: Java StreamAPI Collections データ変換 集計処理

5月25日 13:36 投稿