我有一个名为Transaction的简单POJO,具有三个私有属性String type,double amount和String id。 在主类中,我创建了一些Transaction实例,这些实例调用如下所示的构造函数-
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功能正常,所以这不会发生。
答案 0 :(得分:3)
lambda:
(a,b) -> {Transaction z = b;
z.setAmount(a.getAmount()+b.getAmount());
return z;}
正在修改b
参数。请记住,分配不会不复制对象,因此Transaction z = b
只是为b
所指向的对象提供了别名。
您可能应该使用reduce
重载,该重载允许指定标识和组合器,而只是创建对象的副本。
答案 1 :(得分:1)
Transaction z = b;// doesn't create a new object.
z.setAmount(a.getAmount()+b.getAmount()); //you actually set a amout to `b` object
return z; // and here you returm `b` object
答案 2 :(得分:0)
使用Optional没关系。您的对象是参考数据类型。
在这里,您复制了对象Transaction z = b;
的引用。它不会创建一个新的。现在,两个变量都指向相同的Transaction
。而且无论您修改z
还是b
,都将最终修改源数据