在Java中用lambda表达式类型转换?

时间:2018-02-14 15:59:57

标签: java lambda casting

我在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添加膨胀函数?

谢谢!

1 个答案:

答案 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,而不是函数引用。