代码之家  ›  专栏  ›  技术社区  ›  Derrick

Java-从旧列表创建新列表,旧列表也会被修改[复制]

  •  1
  • Derrick  · 技术社区  · 6 年前

    我已经使用 addAll() 方法,当我尝试修改新列表时,旧列表也会被修改。

    例如-

    List<A> list = new ArrayList<A>();
            list.add(new A("something1"));
            list.add(new A("something2"));
            list.add(new A("something3"));
            list.add(new A("something4"));
            List<A> newList = new ArrayList<A>();
            newList.addAll(list);
            for(A a1 : newList){
                a1.setA("something new");
            }
    
            System.out.println("list----------------");
            for(A a1 : list){
                System.out.println(a1.toString());
            }
            System.out.println("new list----------------");
            for(A a1 : newList){
                System.out.println(a1.toString());
            }
    

    输出-

      list----------------
    A [a=something new]
    A [a=something new]
    A [a=something new]
    A [a=something new]
    new list----------------
    A [a=something new]
    A [a=something new]
    A [a=something new]
    A [a=something new]
    

    如何防止这种行为并保持原来的列表不变?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Stephen C    6 年前

    (代码的第一个版本有一个拼写错误。我假设这在你的真实代码中不存在。)

    set 方法,这是修改对象。。。不是名单。当然,您可以通过任一列表看到对对象的修改。

    如果你不想发生这种事,你就得加上 副本 从第一个列表中的对象到第二个列表。为此,需要实现一种方法来复制 A . 您可以使用以下方法:

    • 复制构造函数,
    • clone 方法,
    • 代码。

    A ,您只需迭代第一个列表 第二个列表的条目。

        2
  •  2
  •   Dinomaster    6 年前

    Java将对对象的引用存储在一个列表中。因此,如果只创建一个复制列表,那么列表对象是不同的,它仍然使用对a对象的相同引用,换句话说,两个列表中的a对象是相同的。若您想防止这种情况,您将需要制作对象的克隆副本。结果如下:

    List<A> newList = list.stream.map(a -> new A(a.getContent()).collect(Collectors.toList());
    

    或者如果您在

    List<A> newList = list.stream.map(A::clone).collect(Collectors.toList());