【发布时间】:2019-07-02 11:15:45
【问题描述】:
我有一个名为 Transaction 的简单 POJO,它具有三个私有属性 String type、double amount 和 String id。 在主类中,我创建了几个调用构造函数的事务实例,如下所示 -
List<Transaction> transList = Arrays.asList(new Transaction(Transaction.TRANSACTION_TYPE_GROCERY,45.50,"2a"),
new Transaction(Transaction.TRANSACTION_TYPE_GROCERY,50.0,"1a"),
new Transaction(Transaction.TRANSACTION_TYPE_GROCERY,15.00,"3a"),
new Transaction(Transaction.TRANSACTION_TYPE_GROCERY,27.43,"4a"),
new Transaction(Transaction.TRANSACTION_TYPE_CLOTHING,145.0,"5a"),
new Transaction(Transaction.TRANSACTION_TYPE_CLOTHING,105.0,"6a"));
现在我使用下面的代码在这个列表上调用了下面的操作 -
Optional<Transaction> totalA = transList.stream()
.filter(x->x.getType()==Transaction.TRANSACTION_TYPE_GROCERY)
.reduce((a,b) -> {Transaction z = b;
z.setAmount(a.getAmount()+b.getAmount());
return z;});
在这里,我尝试通过将 Transaction 保持为最低单位来执行归约操作,并计算所有交易金额的总和并将其设置在新的 Transaction z 中。所有这些最终都存储为可选。 在此之后,如果我尝试对 transList 数据源执行任何其他操作,我会得到不正确的结果,因为 transList 的状态会被破坏。
List<String> transactionIds = transList.stream()
.filter(x -> x.getAmount()>50.00)
.map(Transaction::getId)
.collect(Collectors.toList());
System.out.println(transactionIds);
我已经使用 reduce() 成功地为这个列表完成了 Optional 包含 Double 项和 double 返回值的实现。 我只想知道 Optional 出了什么问题,以至于它最终修改了数据源本身,这不应该发生,因为 Stream 是正常的。
【问题讨论】:
-
System.out.println(transactionIds) 的结果;应该是 [5a, 6a]。但是,上面的代码在执行时会返回 [1a, 3a, 4a, 5a, 6a]。
-
不要评论您的问题。 编辑它。
-
这看起来很可疑 -
Transaction z = b; z.setAmount(a.getAmount()+b.getAmount());将 b 复制到 z 不会创建对象的副本,因此您实际上是在修改 b。 -
一方面,您的第一个流管道中的
reduce包含一个缺陷,而您返回一个新的Transaction并添加了amount,并且因为type无论如何对他们来说都是相同的(原因:过滤器),您在操作中没有考虑id属性。这就是导致您也不会坚持所有不同的ids 的原因。另一方面,修改现有对象实际上会立即提出这一点。
标签: java java-8 java-stream pass-by-reference reduce