如何在 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 有一个根本性的缺陷。您不会覆盖 equals
或 hashCode
。所以你是在使用对象引用作为键。尝试执行以下操作:
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()));
我有这个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 有一个根本性的缺陷。您不会覆盖 equals
或 hashCode
。所以你是在使用对象引用作为键。尝试执行以下操作:
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()));