I have a piece of code that looks something like this.
I have read two contradicting(?) "rules" regarding this.
.map should not have side effects .foreach should not
update a mutable variable (so if I refactor to use foreach and
populate a result list, then that breaks that) as mentioned in http://files.zeroturnaround.com/pdf/zt_java8_streams_cheat_sheet.pdfHow can I solve it so I use streams and still returns a list, or should I simply skip streams?
@Transactional
public Collection<Thing> save(Collection<Thing> things) {
return things.stream().map(this::save).collect(Collectors.toList());
}
@Transactional
public Thing save(Thing thing) {
// org.springframework.data.repository.CrudRepository.save
// Saves a given entity. Use the returned instance for further operations as the save operation might have changed the entity instance completely.
Thing saved = thingRepo.save(thing);
return saved;
}
Doesn't that paper say shared mutable state? In your case if you declare the list inside the method and then use forEach, everything is fine. The second answer here mentions exactly what you are trying to do.
There is little to no reason to collect a entirely new List if you don't mutate it at all. Besides that your use case is basically iterating over every element in a collection and save that which could simply be achieved by using a for-each.
If for some reason thingRepo.save(thing) mutates the object you can still return the same collection, but at this point it's a hidden mutation which is not clearly visible at all since thingRepo.save(thing) does not suggest that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With