マッピング、Javaの8 Streamsを使用して合計を集計し、構成します

user2936416:

私は、Java 8 Streamsを使用して、オブジェクトの別のリストの集合体であるオブジェクトのリストを作成するプロセスを再作成しようとしています。

例えば、私は、データベースコールまたは類似から提供され、以下に説明するクラスを、有します

public class Order {

    private String orderNumber;        
    private String customerNumber;
    private String customerGroup;
    private Date deliveryDate;
    private double orderValue;
    private double orderQty;
}

他の場所で私のアプリケーションでは、私は注文が顧客番号とグループでグループ化しorderValueとorderQtyの合計を合計するのクラスを表したOrderTotalおよび凝集を持っています。(customerGroupとCUSTOMERNUMBER上のイコールとハッシュコード付き)

public class OrderTotal {

    private String customerGroup;
    private String customerNumber;
    private double totalValue;
    private double totalQty;
}

次のように私たちが前のjava 8にこれを達成している「長針」方法です

public Collection<OrderTotal> getTotals(List<Order> orders) {
    ///map created for quick access to the order total for each order 
    Map<OrderTotal, OrderTotal> map = new HashMap<>();
    ///loop through all orders adding to the relevaent order total per iteration
    for (Order order : orders) {
        OrderTotal orderTotal = createFromOrder(order);
        {
            ///if the order total already exists in the map use that one, otherwise add it to the map.
            OrderTotal temp = map.get(orderTotal);
            if(temp == null){
                map.put(orderTotal, orderTotal);
            }else{
                orderTotal = temp;
            }
        }
        ///add the values to the total 
        aggregate(orderTotal, order);
    }        
    return map.values();
}

private OrderTotal createFromOrder(Order order) {
    OrderTotal orderTotal = new OrderTotal();
    orderTotal.setCustomerGroup(order.getCustomerGroup());
    orderTotal.setCustomerNumber(order.getCustomerNumber());
    return orderTotal;
}

private void aggregate(OrderTotal orderTotal, Order order){
    orderTotal.setTotalQty(orderTotal.getTotalQty() + order.getOrderQty());
    orderTotal.setTotalValue(orderTotal.getTotalValue() + order.getOrderValue());
}

機能によって、縮小、グループ化を使用してコレクターを見ているが、それらはすべての注文クラスを集約するのではなくたOrderTotalクラスの合計を構成するに焦点を当てたように見えるされてアイブ。

私はこのコードからすべての肥大化を削除整頓ストリームまたはコレクト機能を探しています。

Ousmane D .:

あなたは使用することができtoMap、次のようにコレクタ:

Collection<OrderTotal> result = orders.stream()
            .map(o -> createFromOrder(o))
            .collect(toMap(Function.identity(),
                        Function.identity(),
                        (l, r) -> {
                            aggregate(l, r);
                            return l;
                        }))
                .values();

これは変更する必要があることに注意aggregateするメソッドのパラメータをaggregate(OrderTotal orderTotal, OrderTotal order){ ... }両方のパラメータがタイプである。すなわちOrderTotal

またはあなたが削除できaggregate、完全に方法をとのロジックを実行しますtoMap

Collection<OrderTotal> result = orders.stream()
            .map(o -> createFromOrder(o))
            .collect(toMap(Function.identity(),
                    Function.identity(),
                    (l, r) -> {
                        l.setTotalQty(l.getTotalQty() + r.getTotalQty());
                        l.setTotalValue(l.getTotalValue() + r.getTotalValue());
                        return l;
                    }))
            .values();

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=167646&siteId=1