如何在 Java 的 Map 中乘以 key * value?

How to multiply key * value in Map in Java?

我有这个class:

class Product {
    public double price;

    public Product(double price) {
        this.price = price;
    }
}

还有一张地图:

Map<Product, Integer> products = new HashMap<>();

其中包含几个这样添加的产品:

products.put(new Product(2.99), 2);
products.put(new Product(1.99), 4);

我想使用流计算所有乘积值的总和?我试过了:

double total = products.entrySet().stream().mapToDouble((k, v) -> k.getKey().price * v.getValue()).sum();

但它没有编译,我得到“无法解析方法getValue()”。

我预计:

(2.99 * 2) + (1.99 * 4) = 5.98 + 7.96 = 13.94

条目流需要每个条目的单个参数 lambda,而不是 (k,v):

double total = products.entrySet().stream().mapToDouble(e -> e.getKey().price * e.getValue()).sum();

你也可以这样做

double sum = 0;
for(Entry<Product, Integer> e : products.entrySet()) {
    sum += e.getKey().price * e.getValue();
}
System.out.println(sum);

打印

13.940000000000001

但是你的 class 有一个根本性的缺陷。您不会覆盖 equalshashCode。所以你是在使用对象引用作为键。尝试执行以下操作:

System.out.println(products.get(new Product(1.99));

它将打印 null,因为没有该引用的条目(它与用于存储值 4 的对象不同)。

最后你应该确保你的密钥是不可变的。否则,情况可能会导致相同的错误。

查看 why do I need to override hashcode and equals。 既然在评论中提到了它,也请查看 what data type to use for money in java.

与您的问题没有直接关系,但我不会为您正在做的事情使用地图。而是创建一个新的 class

public class ProductAmount {
    private Product product;
    private int amount;

    public ProductAmount(Product product, int amount) {
        this.product = product;
        this.amount = amount;
    }

    public double getCombinedPrice() {
        return product.price * amount;
    }
}

那么您可以使用 List 而不是 Map

List<ProductAmount> products = Arrays.asList(
        new ProductAmount(new Product(2.99), 2),
        new ProductAmount (new Product(1.99), 4)); 
  
products.stream().mapToDouble(ProductAmount::getCombinedPrice).sum();

您可以避免显式创建 doubleStream,例如:

double total = products.entrySet()
                       .stream()
                       .collect(Collectors.summingDouble(e -> e.getKey().price * e.getValue()));