Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么一个arraylist的副本被修改时会发生更改_Java - Fatal编程技术网

Java 为什么一个arraylist的副本被修改时会发生更改

Java 为什么一个arraylist的副本被修改时会发生更改,java,Java,这可能是一个非常简单的问题,但它仍然让我困惑 import java.util.ArrayList; public class Sample { ArrayList<Integer> i = new ArrayList<>(); ArrayList<Integer> j = new ArrayList<>(); /** * @param args */ public static void m

这可能是一个非常简单的问题,但它仍然让我困惑

import java.util.ArrayList;

public class Sample {
    ArrayList<Integer> i = new ArrayList<>();
    ArrayList<Integer> j = new ArrayList<>();

    /**
     * @param args
     */
    public static void main(String[] args) {
        new Sample().go();
    }

    private void go() {

        i.add(1);
        i.add(2);
        i.add(3);

        j=i;

        i.remove(0);


        System.out.println(i + "asd" + j);
    }

}

为什么当我改变时j会改变?但在原语中不会发生这种情况

语句
j=i将引用
j
指定为与
i
相同的引用。现在
i
j
都引用相同的
ArrayList
对象。删除第0个索引只需通过两个引用即可看到

如果希望删除
i
中的项目不会影响
j
中的列表,请创建列表的副本,而不是分配引用:

j = new ArrayList<Integer>(i);
j=新数组列表(i);
(这是一个浅表副本,因此列表仍然引用相同的元素。)

使用

j = new ArrayList<>(i);
创建一个副本


使用
j=i
时,您只能在
i
上指向
j
(称为参考)。这适用于所有涉及对象的赋值(不是像
int
float
这样的基本类型)

对象未克隆,只是添加了一个附加的对象引用。由于ArrayList不是不可变的,因此对对象的任何更改都会反映在对象引用中。

对象和原语的工作方式有所不同。将像
i
这样的对象视为该对象的名称。当你说
j=i
时,你是在告诉JVM“忘记我说的另一个名为
j
ArrayList
;从现在起,当我提到
j
时,我指的是这个
ArrayList
,也可以称为
I
。事实上,事情就是这样:在这一行之后,两个变量都指向同一个对象


原语按您所说的那样工作。如果你说
i=5;j=i;i=6
,则
j
仍将设置为5。

您为j创建了一个内存阶段,其中包含;j=新的ArrayList()<然后你说让j指的是我的记忆阶段。所以在j=i之后;i或j上的任何更改都将影响它们。因为它们引用相同的对象。

让我用以下方式为您执行此操作:

ArrayList<Integer> i = new ArrayList<>();
ArrayList<Integer> j = new ArrayList<>();

// checking hash code before j = i;
System.out.println(System.identityHashCode(i));
System.out.println(System.identityHashCode(j));

j = i;

// checking hash code after j = i;
System.out.println(System.identityHashCode(i));
System.out.println(System.identityHashCode(j));

事实上,所有对象(可变的)都会发生这种情况。在Java中,所有对象都是通过引用传递的,而不是原语类型。(我更正:)@meskobalazs Java中的一切都是通过值传递的。对于对象,引用是通过值传递的。@meskobalazs请参见。是的,我应该更具体一些。您应该搜索Java如何处理内存,特别是对象引用,以及浅复制和深复制之间的区别。
Collections.copy(j, i);
ArrayList<Integer> i = new ArrayList<>();
ArrayList<Integer> j = new ArrayList<>();

// checking hash code before j = i;
System.out.println(System.identityHashCode(i));
System.out.println(System.identityHashCode(j));

j = i;

// checking hash code after j = i;
System.out.println(System.identityHashCode(i));
System.out.println(System.identityHashCode(j));
30269696 //hashCode of i
24052850 //hashCode of j before j = i;

30269696 //hashCode of i and j are same after j = i that means they are pointing to same reference and hence change in one reflects on the other.
30269696