对 lambda 和流的概念有点弱,所以可能有些东西确实没有任何意义,但我会尽力传达我想要发生的事情。
我有一个发票类,其中包含商品名称、价格和数量。 我必须将商品名称映射到总成本(价格*数量)。
虽然它不起作用,但希望它能告诉我我遇到了什么问题:
invoiceList.stream()
.map(Invoice::getDesc)
.forEach(System.out.println(Invoice::getPrice*Invoice::getQty));
我已经知道 forEach 不起作用,因为它映射到变量描述(getDesc),而不是 Invoice 对象,我可以在其中使用它的方法来获取其他变量。
因此,如果item=pencil,price=1,qty=12
,我想要的输出是:
Pencil 12.00
这将在多个 Invoice 对象上完成。
此外,我需要按总数对它们进行排序,并过滤超过一定数量的内容,例如。 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()));
这基本上创建了一个映射,其中键是发票
名称,值是给定发票
的发票价格和数量的乘积。
Using the groupingBy collector
但是,如果可以有多个同名发票,则您可以使用groupingBy
收集器和 summingDouble
作为下游收集器:
Map<String, Double> result =
invoiceList.stream()
.collect(groupingBy(Invoice::getName,
Collectors.summingDouble(e -> e.getPrice() * e.getQuantity())));
这将按发票名称对发票
进行分组,然后对每个组对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));
关于java - Lambda 和流(数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50822047/