我在Java 8下使用Spring Boot,我正在尝试在lambda表达式中执行类型转换,但是在经过大量研究和尝试/错误后无法使其工作。
假设我有一个这样的列表:
List<Foo> list;
在批处理的一个步骤中填充,并且由于数据源限制,类Foo需要像这样声明(其所有成员都是String):
class Foo {
private String id;
private String quantity;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getQuantity {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
}
加载列表后,我需要根据id进行一些分组和求和,假设数量String表示十进制数。
以下代码给出了一个错误,因为 summingDouble 期望一个Double,而不是一个字符串:
Map<String, Double> grouping = list.stream().collect(Collectors.groupingBy(Foo::getId, Collectors.summingDouble(Foo::getQuantity)));
我设法通过向Foo类添加一个额外的函数来修复错误,如下所示:
public Double getQuantityAsDouble() {
return StringUtils.isEmpty(quantity) ? new Double(0) : Double.valueOf(quantity);
}
以这种方式打电话:
Map<String, Double> grouping = list.stream().collect(Collectors.groupingBy(Foo::getId, Collectors.summingDouble(Foo::getQuantityAsDouble)));
但对我来说这似乎是一个糟糕的解决方案。
有没有办法在 Collectors.summingDouble()中将 Foo :: getQuantity 从String转换为Double,而无需向原始bean添加膨胀函数?
谢谢!
答案 0 :(得分:2)
Java没有从String到Double的隐式转换,这正是您的代码所暗示的。
您需要一个显式转换,可以通过流中的转换完成:
Map<String, Double> grouping = list.stream().collect(Collectors.groupingBy(Foo::getId,
Collectors.summingDouble(foo -> Double.parseDouble(foo.getQuantity()))));
(如果那些语义更合适,则使用Double.valueOf)
已编辑:清晰度
EDITED MORE :根据评论添加说明。
双冒号语法(例如Foo::getQuantity
)创建方法引用。 Double.valueOf只知道如何处理字符串。在这种情况下,java需要一些&#34;命令式帮助&#34;连接点,因此是命令式lambda,而不是函数引用。