Java流映射修改不在类中构建的自定义类对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java流映射修改不在类中构建的自定义类对象相关的知识,希望对你有一定的参考价值。

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

内部主要:

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]

这种行为的原因是什么?当更改Employee对象的值时,将在原始ArrayList中更新值,但是当String的StringList更改时,值不会反映在原始ArrayList中。

答案

e.name+="CHANGE"s->s+="CHANGE"之间有不同。它们都创建了一个新的String实例,但是当第一个将新的String分配给Employee类的实例的实例变量(并因此改变该实例)时,第二个将它分配给本地String变量。

因此e.name+="CHANGE"改变了原始List的相应实例,s->s+="CHANGE"没有。

另一答案

这个问题与流无关。

在这个lambda表达式:s -> s += "CHANGE"中,你只是重新分配局部变量ss += "CHANGE"还返回串联的结果,这解释了流显示映射值的原因。此重新分配仅在lambda表达式的本地范围内有效。

但是e.name+="CHANGE"更新了Employee对象e的领域。这会更新原始对象本身。

您应该收集映射值而不是更新原始流元素。顺便说一句,更新原始流元素甚至不是您的选项,因为您无法修改String对象。

以上是关于Java流映射修改不在类中构建的自定义类对象的主要内容,如果未能解决你的问题,请参考以下文章

ObjectMapper 无法处理带有遗留枚举(类)的映射对象

java有A,B两个类,A类中有一个变量x,这个变量值在A类中改变了值,如何在B类中取得这

java - 如何将responseEntity映射到java中的自定义类

如何在多个java类中自动修改代码?

生成的自定义托管对象类不构建

将整数映射到组合框中的自定义类的字符串