Неверный тип возврата в лямбда-выражении: BigDecimal не может быть преобразован в long

Я пытался написать запрос в потоке Java, через ускорение. Когда я пытаюсь sum (l_extendedprice * (1 - l_discount)) в избранном я получаю эту ошибку:

Неверный тип возврата в лямбда-выражении: BigDecimal не может быть преобразовано в long. Оператор '-' не может быть применен к 'int', 'java.math.BigDecimal'.

Мой код такой:

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()))
        ));

Как я могу решить это?

1 ответ

Так что проблема в том, что +, -, *, /... не работают с BigDecimal s. Вы должны использовать .add(), .subtract(), .multiply(), .divide()... методы для расчетов.

Если это возможно, вы можете использовать BigDecimal.longValue() или же BigDecimal.longValueExact() преобразовать BigDecimal s для длинных значений, чтобы использовать их в своих вычислениях:

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()))
        ));

В качестве альтернативы вы можете выполнить весь расчет с помощью BigDecimal и преобразовать значение в long в конце:

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())
        ));

Если оба решения не работают для вас, вы должны написать собственную коллекцию для BigDecimalSummaryStatistics или просто рассчитайте нужные вам значения напрямую. Вы можете прочитать этот вопрос для подведения итогов BigDecimal значения с использованием Java Stream.

Другие вопросы по тегам