ホーム > Java > Stream > 終端処理

終端処理

1. リストをグルーピングする

例)List<注文明細> から Map<注文番号, 注文明細>を生成する。

注文明細クラスは以下の通り

@Getter
@AllArgsConstructor
@ToString
public class OrderDetail {
    private final Integer orderNo;
    private final String itemCd;
    private final Integer quantity;
}

リストの内容は以下のとおりとする

OrderDetail(orderNo=1, itemCd=a001, quantity=1)
OrderDetail(orderNo=1, itemCd=b001, quantity=1)
OrderDetail(orderNo=2, itemCd=c001, quantity=1)
OrderDetail(orderNo=2, itemCd=d001, quantity=1)
OrderDetail(orderNo=3, itemCd=e001, quantity=1)

Stream処理

Map<Integer, List<OrderDetail>> resultMap = list.stream()
    .collect(Collectors.groupingBy(OrderDetail::getOrderNo));

resultMap.entrySet().forEach(System.out::println);

実行結果

1=[OrderDetail(orderNo=1, itemCd=a001, quantity=1), 
   OrderDetail(orderNo=1, itemCd=b001, quantity=1)]
2=[OrderDetail(orderNo=2, itemCd=c001, quantity=1), 
   OrderDetail(orderNo=2, itemCd=d001, quantity=1)]
3=[OrderDetail(orderNo=3, itemCd=e001, quantity=1)]

2. リストを集約する

例)List<注文明細> から 注文番号ごとに集約されたCollection<注文>を生成する。 処理の都合上、一度Map<注文番号, 注文>に格納する

注文クラスは以下の通りとする

@Getter
@ToString
public class Order {
    private final Integer orderNo;
    private final List<OrderDetail> orderDetails;

    public Order (OrderDetail orderDitail) {
        this.orderNo = orderLine.getOrderNo();
        orderDetails = new ArrayList<>();
        orderDetails.add(orderDitail);
    }
}

リストの内容は1.と同じ

Stream処理

Collection<Order> results = list.stream().collect(Collectors.toMap(
        OrderDetail::getOrderNo, // Mapのkey(注文番号)
        Order::new,              // Mapの値(注文)
        (s, a) -> {              // keyが重複した時の処理(集約処理)
            s.getOrderDetails().addAll(a.getOrderDetails());
            return s;
        })).values();  // Map.values()のみ取得

results.forEach(System.out::println);

実行結果

Order(orderNo=1, 
      orderDetails=[OrderDetail(orderNo=1, itemCd=a001, quantity=1), 
                    OrderDetail(orderNo=1, itemCd=b001, quantity=1)])
Order(orderNo=2, 
      orderDetails=[OrderDetail(orderNo=2, itemCd=c001, quantity=1), 
                    OrderDetail(orderNo=2, itemCd=d001, quantity=1)])
Order(orderNo=3, 
      orderDetails=[OrderDetail(orderNo=3, itemCd=e001, quantity=1)])

3. Collectorsを使用せずにリストを集約する

対象データ、処理結果は2.と同じ

Stream処理

Collection<Order> results = list.stream().collect(
        HashMap<Integer, Order>::new,  // 処理結果を格納するMap
        (map, od) -> {                 // 処理済みmap, 処理対象注文明細
            // 集約処理
            map.compute(od.getOrderNo(), (orderNo, order) -> {
                if (order == null) {
                    return new Order(od);
                } else {
                    order.getOrderDetails().add(od);
                    return order;
                }
            });
        },
        (tMap, uMap) -> {  // 処理済みmapを合成
            uMap.forEach((uk, uv) -> {
                tMap.compute(uk, (k, v) -> {
                    if (v == null) {
                        return uv;
                    } else {
                        v.getOrderDetails().addAll(uv.getOrderDetails());
                        return v;
                    }
                });
            });
        }).values();

results.forEach(System.out::println);

Stream

リンク

コーポレートサイトにちょうどいいCMS、baserCMS