Reputation: 16661
Is there is a way to convert the following code to 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 streams complains about no final variable tmp ? Is there a way to solve such situations ?
Local variable tmp defined in an enclosing scope must be final or effectively final
Upvotes: 3
Views: 4270
Reputation: 314
Use an AtomicReference variable.
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());
Output
"C:\Program Files\Java\jdk1.8.0_261\bin\java.exe...
276.82
Process finished with exit code 0
Upvotes: 0
Reputation: 159096
First, change the code to use generics and an enhanced for
loop. Assuming values
is then a List<DiscountValue>
, this is what you get:
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);
}
I'd suggest staying with that, and not convert it to streams, but if you insist, you can use a one-element array as a value-holder.
Note that ret
and tmp
doesn't have to be declared final
, as long as they are effectively-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);
});
As you can see, you haven't gained anything by using streams. The code is actually worse, so ... don't.
Upvotes: 8