我有产品清单。我想对具有相同 id 的所有数据求和
public class Product {
private int id;
private String name;
private double price;
private int quantity;
.....
}
我将数据添加到列表中
List<Product> products = new ArrayList<>();
products.add(new Product(1, "x", 100, 4));
products.add(new Product(4, "y", 200, 2));
products.add(new Product(4, "y", 50, 5));
products.add(new Product(8, "k", 50, 1));
products.add(new Product(10, "m", 1000, 1));
products.add(new Product(1, "x", 100, 1));
到目前为止,我已经尝试过
Map<Integer, Double> productsByNameCategoryType = products.stream()
.collect(Collectors.groupingBy(Product::getId,
Collectors.collectingAndThen(
Collectors.summarizingDouble(Product::getPrice),
p -> p.getSum())
));
这离我的期望太远了还在尝试中 我对输出的期望是
1、x、200、5
4, y, 250, 7
8、k、50、1
10、米、1000、1
“...我有产品列表。我想对具有相同 id 的所有数据求和...”
创建一个新的 List 以包含合并的 Product 值。
遍历 products,然后从 i + 1 开始子遍历剩余条目。
合并 Product 值,然后添加到新的 List(如果它尚未包含 id)。
List<Product> l = new ArrayList<>();
Product p, t;
int i, j, k, n = products.size(), m;
boolean b;
for (i = 0; i < n; i++) {
p = products.get(i);
for (j = i + 1; j < n; j++)
if (p.getId() == (t = products.get(j)).getId()) {
p.setPrice(p.getPrice() + t.getPrice());
p.setQuantity(p.getQuantity() + t.getQuantity());
}
b = false;
for (k = 0, m = l.size(); k < m; k++)
if (l.get(k).getId() == p.getId()) {
b = true;
break;
}
if (!b) l.add(p);
}
为了简化流程,请提供方法来合并值。
class Product {
...
void merge(Product p) {
price += p.getPrice();
quantity += p.getQuantity();
}
...
}
for (j = i + 1; j < n; j++)
if (p.getId() == (t = products.get(j)).getId())
p.merge(t);
或者,封装 ArrayList 类,并实现 merge 方法。
class ProductList extends ArrayList<Product> {
@Override
public boolean add(Product product) {
return merge(product);
}
boolean merge(Product p) {
for (Product v : this)
if (p.getId() == v.getId()) {
v.setPrice(p.getPrice() + v.getPrice());
v.setQuantity(p.getQuantity() + v.getQuantity());
return true;
}
return super.add(p);
}
}
ProductList products = new ProductList();
products.add(new Product(1, "x", 100, 4));
products.add(new Product(4, "y", 200, 2));
products.add(new Product(4, "y", 50, 5));
products.add(new Product(8, "k", 50, 1));
products.add(new Product(10, "m", 1000, 1));
products.add(new Product(1, "x", 100, 1));
输出
1, x, 200.0, 5
4, y, 250.0, 7
8, k, 50.0, 1
10, m, 1000.0, 1
如果您确实想使用 stream,请使用 Collectors#toMap 方法。
并且,通过 collectingAndThen 方法填充 ArrayList 实例;这是一个有点不直观的步骤。
List<Product> l
= products.stream()
.collect(
Collectors.collectingAndThen(
Collectors.toMap(
Product::getId,
x -> x,
(a, b) -> {
Product p = new Product();
p.merge(b);
return p;
}),
x -> new ArrayList<>(x.values())));