Why does one arraylist change when a copy of it is

2020-02-06 10:04发布

Its probably a very simple one but its' still confusing me!

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

}

I tried to print it :

[2, 3]asd[2, 3]

Why does j change when i changes? Does not happen with primitives though!

标签: java
6条回答
Melony?
2楼-- · 2020-02-06 10:25

The Object is not cloned, just an additional object reference has been added. Since ArrayList is not immutable, any change to the object is reflected in both the object references.

查看更多
一夜七次
3楼-- · 2020-02-06 10:27

Let me do this in the following way for you:

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

compare both the values if they are same that means after j=i; ArrayList j is now pointing to ArrayList i

In my machine o/p was:

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
查看更多
家丑人穷心不美
4楼-- · 2020-02-06 10:34

The statement j=i; assigns the reference j to be the same reference as i. Now both i and j refer to the same ArrayList object. The removal of the 0th index is simply visible through both references.

If you would like the removal of an item in i not to affect the list from j, then create a copy of the list, instead of assigning the references:

j = new ArrayList<Integer>(i);

(It's a shallow copy, so the lists still refer to the same elements.)

查看更多
乱世女痞
5楼-- · 2020-02-06 10:36

You created a memory stage for j with ; j = new ArrayList<>();
but then you said that let j refer to i's memory stage. So after j=i; any changes on i or j are going to effect both of them. Because they reference to the same objects.

查看更多
男人必须洒脱
6楼-- · 2020-02-06 10:39

Objects and primitives work somewhat differently. Think of an object like i as being the name of that object. When you say j=i you're telling the JVM "forget about that other ArrayList that I said was called j; from now on when I refer to j, I mean this ArrayList that can also be called i. And indeed, that's exactly what happened: after that line, both variables refer to the same object.

Primitives work as you say. If you say i=5; j=i; i=6, then j will still be set to 5.

查看更多
Deceive 欺骗
7楼-- · 2020-02-06 10:44

Use

j = new ArrayList<>(i);

or

Collections.copy(j, i);

to create a copy.

With j = i you only make j point on i (it's called reference). This applies to all assignments that involve objects (not primitive types like int or float)

查看更多
登录 后发表回答