繁体   English   中英

如何在嵌套列表中使用 groupingBy

[英]How to use groupingBy on nested lists

我面临一个棘手的情况,我必须在具有嵌套列表的 object 上使用 groupingBy。 我用 map()、flatmap()、toMap() 尝试了一些东西,但无法提出解决方案,只能绕圈子。 非常感谢 stream 专家的任何帮助。 我需要在我的 OrdersAnalyzer class 中实现 2 个方法。 这是我的对象的样子:

public class Order {
  private final String id;
  private final Set<OrderLine> orderLines = new HashSet<>();
  private final Customer customer;

  //getters, setters, equals, hashcode omitted for brevity
}
public class OrderLine {
  private final Product product;
  private final Integer quantity;

  //getters, setters, equals, hashcode omitted for brevity
}
public class Product {
  private final String name;
  private final BigDecimal price;

  //getters, setters, equals, hashcode omitted for brevity
}
public class OrdersAnalyzer {
    /**
     * Should return at most three most popular products. Most popular product is the product that have the most occurrences
     * in given orders (ignoring product quantity).
     * If two products have the same popularity, then products should be ordered by name
     *
     * @param orders orders stream
     * @return list with up to three most popular products
     */
    public List<Product> findThreeMostPopularProducts(Stream<Order> orders) {
      orders.forEach(order -> {
        order.getOrderLines().stream().collect(
          Collectors.groupingBy(OrderLine::getProduct, *What to add here?* )
        );
      });
    }

    /**
     * Should return the most valuable customer, that is the customer that has the highest value of all placed orders.
     * If two customers have the same orders value, then any of them should be returned.
     *
     * @param orders orders stream
     * @return Optional of most valuable customer
     */
    public Optional<Customer> findMostValuableCustomer(Stream<Order> orders) {
      orders.collect(
        Collectors.groupingBy(Order::getCustomer, *What to add here?*)
      );
    }
}

找三个最受欢迎的产品

您希望支持的 API 需要您创建产品的频率 map 以在您找到top-N时进行查找。 在这种情况下, Collectors.counting()将是一个很好的downstream使用。

请注意,它会为您提供Map<Product, Long> productFrequency作为结果,然后您需要定义一个自定义Comparator<Map.Entry<Product, Long>>辅助检查名称比较。

此外,遍历此 map 的条目,同时对 N 个元素进行sortlimit将使您更接近您正在寻找的答案。


找到最有价值的客户

在此 API 中,您希望根据客户各自订单中的最高价值来比较客户。 因此,对于下游的默认toList ,分组就足够了。

它可以帮助您使用Map<Customer, List<Order>> ,其中您需要从每个客户的所有订单中找到价格max的条目。

因此,比较器如Comparator.comparing(e -> findHighestValueOrder(e.getValue()) ,其中e.getValue()List<Order> customerOrders将帮助您解决问题。

我会把findHighestValueOrder的实现留给你,因为如果你知道如何mapflatMap ,你只需要在这些订单中找到max价格或回退到一些默认值,例如BigDecimal.ZERO

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM