I was trying to write a query in java stream, through speedment.
When I try to sum (l_extendedprice * (1 - l_discount))
in select, I get this error:
Bad return type in lambda expression: BigDecimal cannot be converted to long. Operator '-' cannot be applied to 'int', 'java.math.BigDecimal'.
My code is this:
JoinComponent joinComponent = app.getOrThrow(JoinComponent.class);
Join<Tuple6<Customer, Orders, Lineitem, Supplier, Nation, Region>> join = joinComponent
.from(CustomerManager.IDENTIFIER)
.innerJoinOn(Orders.O_CUSTKEY).equal(Customer.C_CUSTKEY)
.where(Orders.O_ORDERDATE.greaterOrEqual(sqlDate))
.where(Orders.O_ORDERDATE.lessThan(sqlDate2))
.innerJoinOn(Lineitem.L_ORDERKEY).equal(Orders.O_ORDERDATE)
.innerJoinOn(Supplier.S_SUPPKEY ).equal(Customer.C_NATIONKEY)
.innerJoinOn(Nation.N_NATIONKEY).equal(Supplier.S_NATIONKEY)
.innerJoinOn(Region.R_REGIONKEY).equal(Nation.N_REGIONKEY)
.where(Region.R_NAME.equal("ASIA"))
.build(Tuples::of);
Comparator<Tuple1<String>> comparator = Comparator
.comparing((Function<Tuple1<String>, String>) Tuple1::get0)
.thenComparing(Tuple1::get0);
Map<Tuple1<String>, LongSummaryStatistics> grouped = join.stream()
.collect(groupingBy(t -> Tuples.of(t.get4().getNName()),
() -> new TreeMap<>(comparator),
summarizingLong(t->t.get2().getLDiscount()*(1-t.get2().getLDiscount()))
));
How can I resolve this?
So the problem is that +
, -
, *
, /
, ... are not working with BigDecimal
s. You have to use .add()
, .subtract()
, .multiply()
, .divide()
, ... methods for calculations.
If it is possible, you can use BigDecimal.longValue()
or BigDecimal.longValueExact()
to convert the BigDecimal
s to long values to use them in your calculation:
Map<Tuple1<String>, LongSummaryStatistics> grouped = join.stream()
.collect(Collectors.groupingBy(Tuples::of,
() -> new TreeMap<>(comparator),
Collectors.summarizingLong(t -> t.get2().getLDiscount().longValue() *
(1 - t.get2().getLDiscount().longValue()))
));
Alternatively you can du the whole calculation with BigDecimal
and convert the value to long at the end:
Map<Tuple1<String>, LongSummaryStatistics> grouped = join.stream()
.collect(Collectors.groupingBy(Tuples::of,
() -> new TreeMap<>(comparator),
Collectors.summarizingLong(t -> t.get2().getLDiscount()
.multiply(BigDecimal.ONE
.subtract(t.get2().getLDiscount())).longValue())
));
If both solutions do not work for you you have to write an own collection for BigDecimalSummaryStatistics
or just calculate the values you need directly. You can read this question for summarizing BigDecimal
values using Java Stream.