.map and mutation of original object's content

Viewed 242

Consider this code

List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee("A", "B"));
employees.add(new Employee("A1", "B1"));
    
employees.stream().map(e-> { e.setfName("Mr. " + e.getfName()); return e; }); // 1. DOES NOT mutate employees' content

employees.stream().map(e-> { e.setfName("Mr. " + e.getfName()); return e; }).collect(Collectors.toList()); // 2. DOES mutate employees' content

employees.stream().map(e-> new Employee ("Mrs. " + e.getfName(), e.getlName())).collect(Collectors.toList()); // 3. DOES NOT put new objects in original list

Not sure if I understand the reason for this behavior. If the stream does create a separate memory, shouldn't 2 also NOT mutate the original list's content?

2 Answers
employees.stream().map(e-> { e.setfName("Mr. " + e.getfName()); return e; }); // 1. DOES NOT mutate employees' content

Line 1 only doesn't mutate employees' content because it doesn't do anything at all. Streams aren't evaluated until a terminal operation is called.

Line 2 creates a new list to hold the updated employees, but the original employees are updated -- so you have two independently modifiable lists that contain exactly the same employees with exactly the same data where you can't modify one without the other. So with the result of line 2, you could add new Employee objects and not modify employees, but you couldn't modify the employees in that List without modifying the originals too (because they're the same employees).

Only Line 3 creates new Employee objects which exist independently of the originals.

An important thing to understand about streams is that they are lazy. If you map the values, the mapping function is only called when you retrieve values from the stream. collecting a stream is one way to use the values and force the mutations, which is why the second example mutates the list and the first one doesn't. The third example doesn't mutate the objects in place, instead creating a new Employee for each one, so it creates a new cloned list that is unrelated to the original list.

Related