首页 > 解决方案 > 分组,求和然后对事务对象列表进行排序java

问题描述

我有一个按日交易的列表,交易包含以下属性:

Transaction(int transactionID,
                       DateTime transactionDate,
                       String shopId,
                       int productReference,
                       int quantity,
                       float price);

有一个列表List<Transaction>,我想按商店提取前 100 名销售的产品。

因此,我需要先按 shopId 对交易进行分组,然后再按 productReference 对交易进行分组,然后对数量求和,而不是从最畅销到最少进行排序。

感谢您的帮助

标签: listsortingjava-8group-by

解决方案


我建议使用附加Product类型,被覆盖equals()并且hasCode()仅包含shopIdproductReference。新类型将作为输出,这将使所有转换工作更加明显。考虑我的版本,使用Lombok lib

import lombok.*;

@Data
@RequiredArgsConstructor(staticName = "of")
@ToString
public class Product {

    final String shopId;
    final int productReference;
}

功能代码本身:

    List<Product> products = transactions.stream()
            // grouping transactions by the same product
            .collect(Collectors.groupingBy(transaction -> Product.of(
                    transaction.getShopId(),
                    transaction.getProductReference())))
            .entrySet().stream()
            // summing all price * quantity occurrences to find top sellings
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    e -> e.getValue().stream()
                            .mapToDouble(p -> p.getQuantity() * p.getPrice())
                            .sum()))
            .entrySet().stream()
            // sorting by the most expensive ones at the top, 
            // limiting to 10 and collecting to the list 
            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
            .map(Map.Entry::getKey)
            .limit(10)
            .collect(Collectors.toList());

推荐阅读