【问题标题】:Solve no final variable inside Java 8 Stream解决 Java 8 Stream 中没有最终变量的问题
【发布时间】:2016-07-14 13:00:44
【问题描述】:

有没有办法将以下代码转换为 Java 8 Stream。

    final List ret = new ArrayList(values.size());
    double tmp = startPrice;
    for (final Iterator it = values.iterator(); it.hasNext();) {
      final DiscountValue discountValue = ((DiscountValue) it.next()).apply(quantity, tmp, digits, currencyIsoCode);
      tmp -= discountValue.getAppliedValue();
      ret.add(discountValue);
    }

Java 8 流抱怨没有最终变量 tmp ?有没有办法解决这种情况?

在封闭范围内定义的局部变量 tmp 必须是 final 或有效 final

【问题讨论】:

  • 第 1 步:使用泛型,而不是 raw Iterator。为什么values 是原始的Collection,而不是通用的Collection<DiscountValue>
  • 增强的 for 循环在这里会更有意义。
  • 我没有看到任何可能抱怨没有最终变量 tmp 的 Stream 代码...
  • 为什么apply方法需要tmp变量?
  • 好吧,如果你想将它转换为 java 8 流,你应该从循环中删除突变并使用 map 和/或 reduce。将其 1:1 转换为 java 8 forEach 有点毫无意义。如果您不想更改逻辑,则应将其转换为泛型 + 普通 foreach 循环。

标签: java java-8 java-stream


【解决方案1】:

首先,更改代码以使用泛型和增强的for 循环。假设 valuesList<DiscountValue>,这就是你得到的:

List<DiscountValue> ret = new ArrayList<>(values.size());
double tmp = startPrice;
for (DiscountValue value : values) {
    DiscountValue discountValue = value.apply(quantity, tmp, digits, currencyIsoCode);
    tmp -= discountValue.getAppliedValue();
    ret.add(discountValue);
}

我建议保留它,不要将其转换为流,但如果您坚持,您可以使用单元素数组作为值持有者。

请注意,rettmp 不必声明为 final,只要它们是有效最终的。

List<DiscountValue> ret = new ArrayList<>(values.size());
double[] tmp = { startPrice };
values.stream().forEachOrdered(v -> {
    DiscountValue discountValue = v.apply(quantity, tmp[0], digits, currencyIsoCode);
    tmp[0] -= discountValue.getAppliedValue();
    ret.add(discountValue);
});

如您所见,您没有通过使用流获得任何收益。代码实际上更糟糕,所以... 不要

【讨论】:

    【解决方案2】:

    使用 AtomicReference 变量。

    AtomicReference<Double> temp = new AtomicReference<>();
    temp.set(356.65);
    
    Double[] values = {23.4, 45.6,9.4,1.43};
    
    Stream.of(values).forEach(val -> {
              temp.set(temp.get() - val);
    });
    
    System.out.println(temp.get());
    

    输出

    "C:\Program Files\Java\jdk1.8.0_261\bin\java.exe...
    276.82
    
    Process finished with exit code 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-11
      • 1970-01-01
      相关资源
      最近更新 更多