Reputation: 11687
ArrayList<ArrayList<String>> list1 = new ArrayList<ArrayList<String>>();
ArrayList<String> list2 = new ArrayList<String>();
list2.add("foo");
System.out.println(list2); //[foo]
list1.add(list2);
System.out.println(list1); //[[foo]]
list2.set(0, "bar");
System.out.println(list2); //[bar]
System.out.println(list1); //[[bar]]
The code above shows 2 lists. When I add list2
(containing foo
) to list1
they both now contain foo
. But when I modify list2
to bar
, list1
will change as well. I've always thought the add method only gives a copy of list2
to list1
and what I do to list2
will not change for list1
.
How can I make it that I add list2
to list1
but allow list2
to be freely modified in the future so list1
will not be affected again?
Upvotes: 0
Views: 2934
Reputation: 533492
In Java references are passed by value, not the object referenced. This means that list2.add(list1);
cannot alter the reference list1
but it takes a reference to the same object and if you change that it is visible.
The way you should write this is
List<List<String>> list1 = new ArrayList<List<String>>();
List<String> list2 = new ArrayList<String>();
list2.add("foo");
System.out.println(list2); //[foo]
list1.add(new ArrayList<String>(list2)); // take a copy of the list.
System.out.println(list1); //[[foo]]
list2.set(0, "bar");
System.out.println(list2); //[bar]
System.out.println(list1); //[[foo]]
or
list1.add(list2);
list2 = new ArrayList<String>();
list2.add("bar");
System.out.println(list2); //[bar]
System.out.println(list1); //[[foo]]
My example above is simple but my actual problem is buried in nested loops and such.
List<List<String>> list1 = new ArrayList<List<String>>();
for(some loop) {
List<String> list2 = new ArrayList<String>();
// populate list2, can be smaller than the previous list2 !!
list1.add(list2);
}
Upvotes: 6
Reputation: 161
How about list1.add(list2.clone());
?
This will create a copy of list2
(allocate memory, clone contents etc) and put reference to it in list1
.
Upvotes: 1