Java8: изменить ссылку на переменную вне forEach - PullRequest
2 голосов
/ 16 марта 2020

Я пытаюсь сделать две вещи одновременно:

1.Сумма значений из указанного поля c объектов в списке

AtomicReference<BigDecimal> doReqQtySum = new AtomicReference<>(BigDecimal.ZERO);
AtomicReference<BigDecimal> boQtySum = new AtomicReference<>(BigDecimal.ZERO);
models.forEach(detail -> {
    doReqQtySum.accumulateAndGet(detail.getDoReqQty(), (bg1, bg2) -> bg1.add(bg2));
    boQtySum.accumulateAndGet(detail.getBoQty(),  (bg1, bg2) -> bg1.add(bg2));
});

2. Фильтрация объекта из списка

DoRequestDetailModel originProductRequestDetail = models.stream()
    .filter(m -> m.getIsOriginProduct())
    .reduce((a, b) -> {
         throw new IllegalStateException();
    })
    .get();

Я хотел бы этот код, но он не работает:

AtomicReference<BigDecimal> doReqQtySum = new AtomicReference<>(BigDecimal.ZERO);
AtomicReference<BigDecimal> boQtySum = new AtomicReference<>(BigDecimal.ZERO);
DoRequestDetailModel originProductRequestDetail = new DoRequestDetailModel();
models.forEach(detail -> {
     doReqQtySum.accumulateAndGet(detail.getDoReqQty(), (bg1, bg2) -> bg1.add(bg2));
     boQtySum.accumulateAndGet(detail.getBoQty(),  (bg1, bg2) -> bg1.add(bg2));
     if(detail.getIsOriginProduct()) {
          originProductRequestDetail = detail;
     }
});

Следующий код может быть сделан

AtomicReference<BigDecimal> doReqQtySum = new AtomicReference<>(BigDecimal.ZERO);
AtomicReference<BigDecimal> boQtySum = new AtomicReference<>(BigDecimal.ZERO);
List<DoRequestDetailModel> tempList = new ArrayList<>();
models.forEach(detail -> {
    doReqQtySum.accumulateAndGet(detail.getDoReqQty(), (bg1, bg2) -> bg1.add(bg2));
    boQtySum.accumulateAndGet(detail.getBoQty(),  (bg1, bg2) -> bg1.add(bg2));
    if(detail.getIsOriginProduct()) {
         tempList.add(detail);
    }
});

Есть ли лучшее решение?

1 Ответ

1 голос
/ 16 марта 2020

Вам также придется использовать AtomicReference:

AtomicReference<BigDecimal> doReqQtySum = new AtomicReference<>(BigDecimal.ZERO);
AtomicReference<BigDecimal> boQtySum = new AtomicReference<>(BigDecimal.ZERO);
AtomicReference<DoRequestDetailModel> originProductRequestDetail = new AtomicReference<>(new DoRequestDetailModel());
models.forEach(detail -> {
     doReqQtySum.accumulateAndGet(detail.getDoReqQty(), (bg1, bg2) -> bg1.add(bg2));
     boQtySum.accumulateAndGet(detail.getBoQty(),  (bg1, bg2) -> bg1.add(bg2));
     if(detail.getIsOriginProduct()) {
          if(originProductRequestDetail.get()) throw new IllegalStateException();
          originProductRequestDetail.set(detail);
     }
});

Это потому, что вы изменяете ссылку на внешнюю переменную в области действия функции, вызываемой внутри forEach. Здесь является связанным вопросом.

...