Before reading this answer you may want to familiarize yourself with What is the difference between a variable, object, and reference?
This is what you have now
ArrayList<ArrayList<Integer>> outer = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> inner = new ArrayList<Integer>();
will create
outer -> []
inner -> []
which creates two separate lists and stores reference to them in variables outer
and inner
.
After
inner.add(100);
inner.add(200);
your situation looks like
outer -> []
inner -> [100, 200]
Here comes confusing part
outer.add(inner);
outer.add(inner);
Here value of inner
variable (so reference to list [100, 200]) is placed in outer
list two times. This means that outer
"points to" [100, 200] list two times
//note: `reference1` == `reference2` (like 42 == 42) since they point to same object
outer -> [ reference1, reference2 ]
| |
+-------+ |
+---------------------+
↓
inner +-> [100, 200]
This means that if you change state of list [100, 200] you will be able to see these changes using outer.get(0)
or outer.get(1)
or inner
, since all of them are reference to same list.
So if we use
outer.get(0).add(300);
the outer.get(0)
returns reference to same list as inner
and add(300)
adds new element to that list. Which means that after it new situation will look like
outer -> [ reference1 , reference2 ]
| |
+-------+ |
+---------------------+
↓
inner -> [100, 200, 300]
That is why when you print outer
you are seeing
[[100, 200, 300], [100, 200, 300]].
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
from get(0) from get(1)
What you actually need is to create separate list so reference1
and reference2
will point to two separate lists. Something like
outer -> []
inner1 -> [100, 200]
inner2 -> [100, 200]
which will be later organized into
outer -> [ reference1 , reference2 ]
| |
+------+ |
↓ |
inner1 -> [100, 200] |
|
+--------------------+
↓
inner2 -> [100, 200]
You can do it this way
List<List<Integer>> outer = new ArrayList<List<Integer>>();
List<Integer> inner1 = new ArrayList<Integer>();
List<Integer> inner2 = new ArrayList<Integer>();
inner1.add(100);
inner1.add(200);
inner2.add(100);
inner2.add(200);
outer.add(inner1);
outer.add(inner2);
outer.get(0).add(300);
System.out.println(outer);
//Output: [[100, 200, 300], [100, 200]]