Pla*_*age 0 java list arraylist java-8 java-stream
假设我有一个对象列表,可称其为具有数量和价格作为字段的对象Order。
例如如下:
对象Order(字段quantity和price)列表包含以下值:
Quantity Price
5 200
6 100
3 200
1 300
Run Code Online (Sandbox Code Playgroud)
现在,我想使用Java-8来获取以以下方式过滤的列表:
Quantity Price
8 200
6 100
1 300
Run Code Online (Sandbox Code Playgroud)
价格是要过滤的唯一值,并对价格具有的任何数量进行求和,我想以此为基础形成一个新列表。
请建议我如何使用Java 8 Lambda表达式来完成此操作,谢谢。
以下Stream是窍门:
List<Order> o = orders.stream().collect(
Collectors.collectingAndThen(
Collectors.groupingBy(Order::getPrice,Collectors.summingInt(Order::getQuantity)),
map -> map.entrySet().stream()
.map(e -> new Order(e.getKey(), e.getValue()))
.collect(Collectors.toList())));
Run Code Online (Sandbox Code Playgroud)
让我们分解一下:
以下代码返回,Map<Integer, Integer>其中包含价格作为键(要作为总和的唯一值)及其总数量。键的方法是Collectors.groupingBy用classifier描述键和downstream限定的值,这将是数量的总和,因此Collectors.summingInt(取决于该quantity类型):
Map<Integer, Integer> map = orders.stream().collect(
Collectors.groupingBy( // I want a Map<Integer, Integer>
Order::getPrice, // price is the key
Collectors.summingInt(Order::getQuantity)) // sum of quantities is the value
Run Code Online (Sandbox Code Playgroud)所需的结构是List<Order>,因此您要使用Collectors.collectingAndThen带有Collector<T, A, R> downstream和的方法Function<R, RR> finisher。的downstream是从所述第一点的分组,整理器将是一个转换Map<Integer, Integer>回List<Order>:
List<Order> o = orders.stream().collect(
Collectors.collectingAndThen(
grouping, // you know this one ;)
map -> map.entrySet()
.stream() // iterate entries
.map(e -> new Order(e.getKey(), e.getValue())) // new Order(qty, price)
.collect(Collectors.toList()))); // as a List<Order>
Run Code Online (Sandbox Code Playgroud)