Bad return type in lambda expression: BigDecimal cannot be converted to long

joaoprog :

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?

Samuel Philipp :

So the problem is that +, -, *, /, ... are not working with BigDecimals. 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 BigDecimals 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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=148849&siteId=1