class Employee {
public String name;
public Integer age;
public Employee(String n, int age) {
this.name = n;
this.age = age;
}
public String toString() {
return this.name+":"+this.age;
}
}
Inside Main:
ArrayList<Employee> list = new ArrayList<>();
list.add(new Employee("NameA", 10));
list.add(new Employee("NameB", 25));
list.add(new Employee("NameC", 30));
list.add(new Employee("NameD", 45));
list.add(new Employee("NameE", 50));
System.out.println(list);//[NameA:10, NameB:25, NameC:30, NameD:45, NameE:50]
list.stream().filter(e->e.age%10==0).map(e->e.name+="CHANGE").collect(Collectors.toList());
System.out.println(list); //[NameACHANGE:10, NameB:25, NameCCHANGE:30, NameD:45, NameECHANGE:50]
ArrayList<String> strList = new ArrayList<>();
strList.add("1");
strList.add("2");
strList.add("3");
strList.add("4");
strList.add("5");
System.out.println(strList);//[1, 2, 3, 4, 5]
List<String> updatedStrList = strList.stream().map(s->s+="CHANGE").collect(Collectors.toList());
System.out.println(updatedStrList);//[1CHANGE, 2CHANGE, 3CHANGE, 4CHANGE, 5CHANGE]
System.out.println(strList);//[1, 2, 3, 4, 5]
What's the reason for this behaviour? When the Employee object's value is being changed the value gets updated in the original ArrayList but when ArrayList of String was changed the values did not reflect in the original ArrayList.
There's a different between e.name+="CHANGE"
and s->s+="CHANGE"
. Both of them create a new String
instance, but while the first assigns that new String
to an instance variable of an instance of the Employee
class (and therefore mutates that instance), the second assigns it to a local String
variable.
Therefore e.name+="CHANGE"
changes the corresponding instance of the original List
and s->s+="CHANGE"
doesn't.
The problem has nothing to do with streams.
In this lambda expression: s -> s += "CHANGE"
, you're just reassigning the local variable s
. s += "CHANGE"
also returns the result of the concatenation, and that explains why the stream shows the mapped value. This reassignment is only effective in the local scope of the lambda expression.
But e.name+="CHANGE"
updates the field of the Employee
object e
. This updates the original object itself.
You should collect mapped values instead of updating original stream elements. Incidentally, updating original stream elements is not even an option in your case because you can't modify String objects.
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