reduce() operation on stream seems to be modifying the source of data (list) Stream API Java 8

PeeCee :

I have a simple POJO called Transaction with three private properties String type,double amount and String id. In main class,I created few instances of Transaction calling the constructor as written below -

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

Now I have called below operation on this listusing below code -

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

Here I have tried to perform reduction operation by keeping Transaction as the lowest unit and calculate the sum of all transaction amounts and set it inside a new Transaction z. All this gets stored finally as Optional. After this, if I try to carry out any other operation on the transList data source,I get incorrect results as the state of transList gets disrupted.

List<String> transactionIds = transList.stream()
                                                .filter(x -> x.getAmount()>50.00)
                                                .map(Transaction::getId)
                                                .collect(Collectors.toList());
System.out.println(transactionIds);

I have done the Optional containing Double item and double return value implementations successfully for this list using reduce(). All I want to know is what is so wrong with the Optional that it ends up modifying the source of data itself, which should not happen as Stream is functional.

Giacomo Alzetta :

The lambda:

(a,b) -> {Transaction z = b;                                                                             
                  z.setAmount(a.getAmount()+b.getAmount());
                  return z;}

Is modifying the b parameter. Keep in mind that an assignement does not copy an object so Transaction z = b is just giving an alias to the object pointed to by b.

You should probably use the reduce overload that allows to specify the identity and combiner, os just create a copy of the object.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=129926&siteId=1