>> anotherArrayList = (ArrayList<Something>) oneArrayList.clone();
>> anotherArrayList.get(0).makeSomeChange();
[quoted text clipped - 5 lines]
>
> Arne
Arne:
I know that it says in the docs that ArrayList.clone() is a shallow copy
and that the elements themselves are not copied. Why then does the
following code produce the following results (or have I gone completely
around the bend today?).
import java.util.*;
public class test9 {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(10);
list1.add(11);
list1.add(12);
ArrayList list2 = (ArrayList)list1.clone();
list1.set(0,20);
list1.add(30);
for (int i=0; i<list1.size(); i++)
System.out.print(list1.get(i)+" ");
System.out.println();
for (int i=0; i<list2.size(); i++)
System.out.print(list2.get(i)+" ");
}
}
C:\Documents and Settings\Knute Johnson>java test9
20 11 12 30
10 11 12

Signature
Knute Johnson
email s/nospam/knute/
Twisted - 04 Aug 2007 01:57 GMT
On Aug 3, 8:28 pm, Knute Johnson <nos...@rabbitbrush.frazmtn.com>
wrote:
> Arne Vajh?j wrote:
> >> anotherArrayList = (ArrayList<Something>) oneArrayList.clone();
[quoted text clipped - 25 lines]
> list1.set(0,20);
> list1.add(30);
These modify the cloned list, not the Integer objects. Try replacing
the Integers with StringBuffers, and change the set line to actually
edit the string buffer, i.e. list1.get(0).append("foobar");
Then your first list output should show the first item with "foobar"
on the end and your fourth added item; your second list output should
still omit the fourth item but also have the first item have "foobar"
on the end.
Patricia Shanahan - 04 Aug 2007 02:03 GMT
>>> anotherArrayList = (ArrayList<Something>) oneArrayList.clone();
>>> anotherArrayList.get(0).makeSomeChange();
[quoted text clipped - 35 lines]
> 20 11 12 30
> 10 11 12
The difference between a deep and shallow clone is difficult to see if
you only add immutable objects, such as Integer:
import java.util.*;
public class ListCloneTest {
public static void main(String[] args) {
ArrayList<StringBuilder> list1 = new ArrayList<StringBuilder>();
list1.add(new StringBuilder("aaa "));
ArrayList list2 = (ArrayList) list1.clone();
StringBuilder builder = list1.get(0);
builder
.append("Both lists point to the same StringBuilder");
for (int i = 0; i < list1.size(); i++)
System.out.print(list1.get(i) + " ");
System.out.println();
for (int i = 0; i < list2.size(); i++)
System.out.print(list2.get(i) + " ");
}
}
aaa Both lists point to the same StringBuilder
aaa Both lists point to the same StringBuilder
Patricia
xz - 04 Aug 2007 04:06 GMT
On Aug 3, 7:28 pm, Knute Johnson <nos...@rabbitbrush.frazmtn.com>
wrote:
> Arne Vajh?j wrote:
> >> anotherArrayList = (ArrayList<Something>) oneArrayList.clone();
[quoted text clipped - 23 lines]
> list1.add(12);
> ArrayList list2 = (ArrayList)list1.clone();
this line copies every item in list1 into list2 such that
list1.get(i) = list2.get(i) for i = 0, 1, 2,
which means, two references (0th item in list1 and 0th item in list2)
point to the same thing, but they themselves are not identical.
> list1.set(0,20);
now you changed the 0th item in list1, in other words, you let the the
0th item in list1, which is a reference, point to another thing (20).
This process has nothing to do with list2, meaning 0th item in list2
still points to 10.
> list1.add(30);
> for (int i=0; i<list1.size(); i++)
[quoted text clipped - 9 lines]
> 20 11 12 30
> 10 11 12
However, as I konw ArrayList can only deal with classes, e.g. Integer,
but not primitive types like int. How come your code compiles?
Arne Vajhøj - 04 Aug 2007 04:11 GMT
>> ArrayList<Integer> list1 = new ArrayList<Integer>();
>> list1.add(10);
>> list1.add(11);
>> list1.add(12);
> However, as I konw ArrayList can only deal with classes, e.g. Integer,
> but not primitive types like int. How come your code compiles?
Newer Java versions (1.5+) can auto convert between int and Integer.
Arne
xz - 04 Aug 2007 04:45 GMT
Do you mean now wherever you can use Integer, you can use int, and
vice versa?
That's cool. Didn't know that before.
On Aug 3, 10:11 pm, Arne Vajh?j <a...@vajhoej.dk> wrote:
> >> ArrayList<Integer> list1 = new ArrayList<Integer>();
> >> list1.add(10);
[quoted text clipped - 6 lines]
>
> Arne
Knute Johnson - 04 Aug 2007 05:55 GMT
> Do you mean now wherever you can use Integer, you can use int, and
> vice versa?
>
> That's cool. Didn't know that before.
Pretty much. I don't know what the performance hit though but it is handy.

Signature
Knute Johnson
email s/nospam/knute/
chucky - 04 Aug 2007 11:23 GMT
On Aug 4, 6:55 am, Knute Johnson <nos...@rabbitbrush.frazmtn.com>
wrote:
> > Do you mean now wherever you can use Integer, you can use int, and
> > vice versa?
>
> > That's cool. Didn't know that before.
>
> Pretty much. I don't know what the performance hit though but it is handy.
I'd say that it is as fast as converting it "by hand", since the
distinction between int and Integer can be done by compiler at compile
time, so there is no runtime overhead.
Arne Vajhøj - 04 Aug 2007 04:13 GMT
>> clone is a shallow clone not a deep clone so yes.
> I know that it says in the docs that ArrayList.clone() is a shallow copy
> and that the elements themselves are not copied. Why then does the
> following code produce the following results (or have I gone completely
> around the bend today?).
As other has already stated, then you are changing the references
in the lists not the objects pointed to by the references.
The docs are correct.
Arne
Knute Johnson - 04 Aug 2007 05:54 GMT
>>> clone is a shallow clone not a deep clone so yes.
>
[quoted text clipped - 9 lines]
>
> Arne
Thanks very much everybody. I was confused when I wrote the test code
because it did copy the references. That was not as I expected. Using
a mutable object it is immediately obvious though.

Signature
Knute Johnson
email s/nospam/knute/