lambda和stream的概念有点弱,因此可能有些东西实际上没有任何意义,但我会尽力传达我想发生的事情。

我有一个发票类,其中有一个项目名称,价格和数量。
我必须将商品名称和总成本(价格*数量)对应起来。

尽管它不起作用,但希望它能使我知道我遇到了什么问题:

invoiceList.stream()
           .map(Invoice::getDesc)
           .forEach(System.out.println(Invoice::getPrice*Invoice::getQty));


我已经知道forEach不能正常工作,因为它映射到变量description(getDesc),而不是Invoice对象,在这里我可以使用它的方法来获取其他变量。

因此,如果item=pencil, price=1, qty=12,我想要的输出是:

Pencil   12.00


这将在多个发票对象上完成。

另外,我需要按它们的总数对其进行排序,并且还要过滤超过一定数量的那些,例如。 100.将它们放置在Map中后,我应该怎么做?

最佳答案

如果您只想打印到控制台,则可以按照以下步骤进行操作:

invoiceList.forEach(i -> System.out.println(i.getName() + "    " + (i.getPrice() * i.getQty())));


如果没有,请继续阅读:

Using the toMap collector

Map<String, Double> result =
     invoiceList.stream()
                .collect(Collectors.toMap(Invoice::getName,
                                  e -> e.getPrice() * e.getQuantity()));


这基本上会创建一个映射,其中键是Invoice名称,值是给定Invoice的发票价格和数量的乘积。

Using the groupingBy collector
但是,如果可以有多个同名发票,则可以将groupingBy收集器与summingDouble一起用作下游收集器:

Map<String, Double> result =
     invoiceList.stream()
                .collect(groupingBy(Invoice::getName,
                  Collectors.summingDouble(e -> e.getPrice() * e.getQuantity())));


这按名称对Invoice进行分组,然后针对每个组对e.getPrice() * e.getQuantity()的结果求和。



更新:

如果要使用toMap版本并过滤结果,然后按值升序排序,可以按以下步骤进行:

Map<String, Double> result = invoiceList.stream()
            .filter(e -> e.getPrice() * e.getQuantity() > 100)
            .sorted(Comparator.comparingDouble(e -> e.getPrice() * e.getQuantity()))
            .collect(Collectors.toMap(Invoice::getName,
                    e -> e.getPrice() * e.getQuantity(),
                    (left, right) -> left,
                    LinkedHashMap::new));


或使用groupingBy方法:

 Map<String, Double> result =
                invoiceList.stream()
                        .collect(groupingBy(Invoice::getName,
                                Collectors.summingDouble(e -> e.getPrice() * e.getQuantity())))
                        .entrySet()
                        .stream()
                        .filter(e -> e.getValue() > 100)
                        .sorted(Map.Entry.comparingByValue())
                        .collect(Collectors.toMap(Map.Entry::getKey,
                                Map.Entry::getValue, (left, right) -> left,
                                LinkedHashMap::new));

10-06 13:48
查看更多