Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 modify stream elements

I wanted to write pure function with Java 8 that would take a collection as an argument, apply some change to every object of that collection and return a new collection after the update. I want to follow FP principles so I dont want to update/modify the collection that was passed as an argument.

Is there any way of doing that with Stream API without creating a copy of the original collection first (and then using forEach or 'normal' for loop)?

Sample object below and lets assume that I want to append a text to one of the object property:

public class SampleDTO {     private String text; } 

So I want to do something similar to below, but without modifying the collection. Assuming "list" is a List<SampleDTO>.

list.forEach(s -> {     s.setText(s.getText()+"xxx"); }); 
like image 201
Zyga Avatar asked Jul 11 '16 08:07

Zyga


People also ask

Does Java stream modify elements?

Streams don't change the original data structure, they only provide the result as per the pipelined methods. Each intermediate operation is lazily executed and returns a stream as a result, hence various intermediate operations can be pipelined.

Does stream filter modify the original list?

That means list. stream(). filter(i -> i >= 3); does not change original list. All stream operations are non-interfering (none of them modify the data source), as long as the parameters that you give to them are non-interfering too.

Does Java 8 support streams?

Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.


1 Answers

You must have some method/constructor that generates a copy of an existing SampleDTO instance, such as a copy constructor.

Then you can map each original SampleDTO instance to a new SampleDTO instance, and collect them into a new List :

List<SampleDTO> output =      list.stream()         .map(s-> {                      SampleDTO n = new SampleDTO(s); // create new instance                      n.setText(n.getText()+"xxx"); // mutate its state                      return n; // return mutated instance                  })        .collect(Collectors.toList()); 
like image 99
Eran Avatar answered Sep 26 '22 14:09

Eran