【问题标题】:Updating the next element in list based on the value from current element根据当前元素的值更新列表中的下一个元素
【发布时间】:2020-01-08 05:49:05
【问题描述】:

我有一个列表 List<CT> 需要使用流一次更新相同的 List<CT>

我们有两个数量字段,如果firstQty 小于secondQty,则在下一条记录中剩余的应该设置为secondQty。仅当currentMonth 指标为真时,我们才进行此计算;

输入:

none
[CT(currentMonth=tue, firstQty=600, secondQty=620,..),           
 CT(currentMonth=false, firstQty=0, secondQty=0,..),        
 CT(currentMonth=false, firstQty=0, secondQty=0,..)]       

输出:

none
[CT(currentMonth=tue, firstQty=600, secondQty=620,..),           
 CT(currentMonth=false, firstQty=0, secondQty=20,..),        
 CT(currentMonth=false, firstQty=0, secondQty=0,..)]       
class CT {       
   Boolean currentMonth;      
   BigDecimal firstQty;      
   BigDecimal secondQty;       
} 
        List<CT> lotsDetailsTpm =  deals.stream()
                .map(dcl ->{
                    BigDecimal diffrence = BigDecimal.ZERO;
                    if(dcl.getCurrentMonth()) {
                        BigDecimal qtyFirst = deals.getFirstQty();
                        BigDecimal qtySecond = deals.getSecondQty();
                        BigDecimal diff = qtySecond.subtract(qtyFirst);
                        dcl.qtySecond(qtySecond.sbtract(diff));
                        if(diff.compareTo(BigDecimal.ZERO) > 1) {
                            //need to update the diff to the next element
                        }
                    }
                    return dcl;
                }).collect(Collectors.toList());

这里的难点是如何保持数量的差异,并使用该值来更新下一个元素。

【问题讨论】:

  • 不要为此使用流。它们不适合涉及元素之间此类操作的任务。
  • 请添加您当前的解决方案尝试。
  • 一种解决方案是使用IntStream 并循环您的集合,就像您在更经典的“for 循环”(类似于IntStream.range(0, collection.size()).forEach(i -&gt; \*do your operations here*\);)中所做的那样。但是,我看不出这样做有什么意义:只需做一个“for循环”,它会更容易阅读。
  • @Abrikot:这只是滥用java-stream。那么我会坚持使用 for 循环。

标签: java java-8 java-stream


【解决方案1】:

您可以使用Stream::reduce 的行为,它适用于两个后续值。

  • &lt;U&gt; U reduce(U identity, BiFunction&lt;U,? super T,U&gt; accumulator, BinaryOperator&lt;U&gt; combiner)

代码:

AList<CT> newList = list.stream().reduce(
    new ArrayList<>(),                             // ArrayList as identity, the storage
    (l, ct) -> {                                   // List and the next CT
        if (l.isEmpty()) {                         // ... if the list is empty, insert CT
            l.add(ct);
        } else if (ct.getCurrentMonth()) {         // .. or else do you calculation
            final CT other = l.get(l.size() - 1);
            final BigDecimal diff = other.getSecondQty().subtract(other.getFirstQty());
            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                ct.setSecondQty(diff);
            }
            l.add(ct);                             // .. add the new item
        }
        return l;                                  // .. and return the whole list
    },
    (l, r) -> l                                    // Finally, the operator returns the list
);

解决方案不是最优的(幸运的是,它没有使用任何删除方法,只是获取),但正在工作。请记住 不适合这种处理,旧的 for 循环会更好,因为您可以轻松地控制循环中的索引。

最后,据我从您的问题中了解到,第 3rd 项也应该有 secondQty 作为 20,因为第 2nd 的 20-0=20支持>。也许我理解错了,但是,它并不重要,也很容易被修改。您可以通过 Stream::reduce 获得想法,并随时将其应用于您的问题。

CT(currentMonth=false, firstQty=0, secondQty=20,..)

【讨论】:

    猜你喜欢
    • 2021-02-15
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多