hak*_*ata 5 java reducing java-stream collectors groupingby
我有一个 Item 类,其中包含代码、数量和金额字段,以及可能包含许多项目(具有相同代码)的项目列表。我想按代码对项目进行分组并汇总它们的数量和金额。
我能够使用流groupingBy和实现一半的目标reduce。分组有效,但减少是将所有分组的项目减少为一个在不同代码(groupingBy键)上重复的单个项目。
不应该在此处减少减少地图中每个代码的项目列表吗?为什么它要为所有人重新调整相同的组合项目。
下面是示例代码。
import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.Map;
class HelloWorld {
public static void main(String[] args) {
List<Item> itemList = Arrays.asList(
createItem("CODE1", 1, 12),
createItem("CODE2", 4, 22),
createItem("CODE3", 5, 50),
createItem("CODE4", 2, 11),
createItem("CODE4", 8, 20),
createItem("CODE2", 1, 42)
);
Map<String, Item> aggregatedItems = itemList
.stream()
.collect(Collectors.groupingBy(
Item::getCode,
Collectors.reducing(new Item(), (aggregatedItem, item) -> {
int aggregatedQuantity = aggregatedItem.getQuantity();
double aggregatedAmount = aggregatedItem.getAmount();
aggregatedItem.setQuantity(aggregatedQuantity + item.getQuantity());
aggregatedItem.setAmount(aggregatedAmount + item.getAmount());
return aggregatedItem;
})
));
System.out.println("Map total size: " + aggregatedItems.size()); // expected 4
System.out.println();
aggregatedItems.forEach((key, value) -> {
System.out.println("key: " + key);
System.out.println("value - quantity: " + value.getQuantity() + " - amount: " + value.getAmount());
System.out.println();
});
}
private static Item createItem(String code, int quantity, double amount) {
Item item = new Item();
item.setCode(code);
item.setQuantity(quantity);
item.setAmount(amount);
return item;
}
}
class Item {
private String code;
private int quantity;
private double amount;
public Item() {
quantity = 0;
amount = 0.0;
}
public String getCode() { return code; }
public int getQuantity() { return quantity; }
public double getAmount() { return amount; }
public void setCode(String code) { this.code = code; }
public void setQuantity(int quantity) { this.quantity = quantity; }
public void setAmount(double amount) { this.amount = amount; }
}
Run Code Online (Sandbox Code Playgroud)
下面是输出。
Map total size: 4
key: CODE2
value - quantity: 21 - amount: 157.0
key: CODE1
value - quantity: 21 - amount: 157.0
key: CODE4
value - quantity: 21 - amount: 157.0
key: CODE3
value - quantity: 21 - amount: 157.0
Run Code Online (Sandbox Code Playgroud)
您不得修改的输入参数Collectors.reducing。new Item()仅执行一次,所有归约操作将共享相同的“聚合实例”。换句话说:地图将包含相同的值实例 4 次(您可以使用System.identityHashCode()或 通过比较引用相等性来轻松检查自己aggregatedItems.get("CODE1") == aggregatedItems.get("CODE2"):)。
相反,返回一个新的结果实例:
final Map<String, Item> aggregatedItems = itemList
.stream()
.collect(Collectors.groupingBy(
Item::getCode,
Collectors.reducing(new Item(), (item1, item2) -> {
final Item reduced = new Item();
reduced.setQuantity(item1.getQuantity() + item2.getQuantity());
reduced.setAmount(item1.getAmount() + item2.getAmount());
return reduced;
})
));
Run Code Online (Sandbox Code Playgroud)
输出:
Map total size: 4
key: CODE2
value - quantity: 5 - amount: 64.0
key: CODE1
value - quantity: 1 - amount: 12.0
key: CODE4
value - quantity: 10 - amount: 31.0
key: CODE3
value - quantity: 5 - amount: 50.0
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5399 次 |
| 最近记录: |