英文:
groupingBy in Streams with CollectingAndThen method -> how to get rid of Optional then use Max on the map
问题
以下是翻译好的内容:
似乎我不太理解 groupingBy 和 collectors 以及 sorting 的概念。
任务:使用 Streams 求订单数量按类别分组的总和。然后获取具有最大数量的类别,并将其作为单行映射行打印在图片上,显示顶部值。
3 个类(2 个记录:Product 和 Order + Main)。在 Main 中有一个新订单的 List。
Product 类:
public record Product(String name, BigDecimal price, String category)
Order 类:
public record Order(Product product, int quantity, BigDecimal discount)
public BigDecimal priceWithDiscount(){
return product.price().multiply(BigDecimal.ONE.subtract(discount));
}
Main 类:
List<Order> orders = List.of(
new Order(new Product("chleb", new BigDecimal(5), "A"), 10, new BigDecimal("0.1")),
new Order(new Product("maslo", new BigDecimal(6), "A"), 5, new BigDecimal("0.2")),
new Order(new Product("szynka", new BigDecimal(25), "B"), 10, new BigDecimal("0")),
new Order(new Product("kielbasa", new BigDecimal(16), "C"), 5, new BigDecimal("0")),
new Order(new Product("woda", new BigDecimal(3), "B"), 15, new BigDecimal("0.1")),
new Order(new Product("ocet", new BigDecimal(3), "A"), 8, new BigDecimal("0.3")),
new Order(new Product("margaryna", new BigDecimal(4), "B"), 12, new BigDecimal("0.5")),
new Order(new Product("maslo", new BigDecimal(8), "C"), 5, new BigDecimal("0.2"))
);
以下是我关于分组的实现:
Map<String, Integer> summedQuantitiesPerCategory = orders //编号 1。
.stream()
.collect(Collectors.groupingBy(p -> p.product().category(),
Collectors.summingInt(p -> p.quantity())
));
summedQuantitiesPerCategory.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue()) // 编号 2。
.limit(1);
问题:
1. 如何摆脱 Optional,并在映射中只看到 Integer 作为值。然后排序应该很容易吧。
2. 如何通过值对映射进行排序,使用 Sorted 方法或者更简单的方法,比如 max?
英文:
Seems like i do not quite understand the concepts of groupingBy & collectors & sorting.
Task: to sum the number of order's quantity grouped by Category using Streams. Then get category with Max quantity and print it out on the picture as single map row with top value
3 classes (2 Records: Product & Order + Main). In Main there is an List.of new orders
Class Product:
public record Product(String name, BigDecimal price, String category)
Class Order:
public record Order(Product product, int quantity, BigDecimal discount)
public BigDecimal priceWithDiscount(){
return product.price().multiply(BigDecimal.ONE.subtract(discount));
}
Class Main
List<Order> orders = List.of(
new Order(new Product("chleb", new BigDecimal(5), "A"),10, new BigDecimal("0.1")),
new Order(new Product("maslo", new BigDecimal(6), "A"),5, new BigDecimal("0.2")),
new Order(new Product("szynka", new BigDecimal(25), "B"),10, new BigDecimal("0")),
new Order(new Product("kielbasa", new BigDecimal(16),"C"),5, new BigDecimal("0")),
new Order(new Product("woda", new BigDecimal(3),"B"),15, new BigDecimal("0.1")),
new Order(new Product("ocet", new BigDecimal(3),"A"),8, new BigDecimal("0.3")),
new Order(new Product("margaryna", new BigDecimal(4),"B"),12, new BigDecimal("0.5")),
new Order(new Product("maslo", new BigDecimal(8),"C"),5, new BigDecimal("0.2"))
)
Below my implementation of grouping:
Map<String, Optional<Integer>> summedQuantitiesPerCategory = orders //no 1.
.stream()
.collect(Collectors.groupingBy(p -> p.product().category(),
Collectors.collectingAndThen(
Collectors.mapping(p -> p.quantity(), Collectors.toList()),
quantity -> quantity.stream().reduce((x, y) -> x + y)
)));
summedQuantitiesPerCategory
.entrySet()
.stream()
.sorted(Comparator.comparing(p -> p.getValue())) // no2.
.limit(1);
Questions:
- How to get rid of this Optional and see only Integer as a value in the map. Then it would be easy to sort i guess
- How to sort map via Value using method Sorted or something more simple like e.g. max?
答案1
得分: 1
你正在使用接受BinaryOperator
的reduce
的单参数版本。你可以传递一个身份值和BinaryOperator
。
quantity -> quantity.stream().reduce(0, (x, y) -> x + y)
或者
quantity -> quantity.stream().reduce(0, Integer::sum)
由于你只想要对数量求和,你可以使用Collectors.summingInt
:
...
.collect(Collectors.groupingBy(p -> p.product().category(),
Collectors.summingInt(p -> p.quantity())));
英文:
You are using the one argument version of reduce
which accepts a BinaryOperator
. You can pass an identity value along with the BinaryOperator
.
quantity -> quantity.stream().reduce(0, (x, y) -> x + y)
or
quantity -> quantity.stream().reduce(0, Integer::sum)
Since you just want to sum the quantity, you can use Collectors.summingInt
...
.collect(Collectors.groupingBy(p -> p.product().category(),
Collectors.summingInt(p -> p.quantity())));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论