如果我更改run()中的dataList,那麼這些更改是否會反映到在其他地方聲明的原始列表中?
是的。您的構造函數將參考收到列表中,而不是它的副本。如果你想複製它,你必須使用LinkedList
copy constructor。然後您將擁有自己的副本。但請注意,兩個列表中的條目仍然是共享的,因爲條目是數組(short[]
),並且數組按引用存儲。
import java.util.*;
public class ListExample {
public static final void main(String[] args) {
List<short[]> list;
// Direct use (no copies)
list = new LinkedList<short[]>();
list.add(new short[] { 0, 0, 0 });
System.out.println("list.size() before direct use: " + list.size());
System.out.println("list.get(0)[0] before direct use: " + list.get(0)[0]);
new DirectUser(list).doSomething();
System.out.println("list.size() after direct use: " + list.size());
System.out.println("list.get(0)[0] after direct use: " + list.get(0)[0]);
// Output, note how both the list and its contents have been changed:
// list.size() before direct use: 1
// list.get(0)[0] before direct use: 0
// list.size() after direct use: 2
// list.get(0)[0] after direct use: 1
// Copying the list, but note that the entries are shared by both lists:
list = new LinkedList<short[]>();
list.add(new short[] { 0, 0, 0 });
System.out.println("list.size() before copy-list use: " + list.size());
System.out.println("list.get(0)[0] before copy-list use: " + list.get(0)[0]);
new CopyListUser(list).doSomething();
System.out.println("list.size() after copy-list use: " + list.size());
System.out.println("list.get(0)[0] after copy-list use: " + list.get(0)[0]);
// Output, note how our list didn't change (it doesn't have a new entry), but
// the entry at index 0 *was* changed:
// list.size() before copy-list use: 1
// list.get(0)[0] before copy-list use: 0
// list.size() after copy-list use: 1
// list.get(0)[0] after copy-list use: 1
// "Deep" copying, both the list and its entries:
list = new LinkedList<short[]>();
list.add(new short[] { 0, 0, 0 });
System.out.println("list.size() before deep-copy use: " + list.size());
System.out.println("list.get(0)[0] before deep-copy use: " + list.get(0)[0]);
new DeepCopyUser(list).doSomething();
System.out.println("list.size() after deep-copy use: " + list.size());
System.out.println("list.get(0)[0] after deep-copy use: " + list.get(0)[0]);
// Output, note that neither the list nor its entries was affected by the call:
// list.size() before deep-copy use: 1
// list.get(0)[0] before deep-copy use: 0
// list.size() after deep-copy use: 1
// list.get(0)[0] after deep-copy use: 0
System.exit(0);
}
static class DirectUser {
List<short[]> items;
DirectUser(List<short[]> items) {
// DirectUser doesn't copy the list
this.items = items;
}
void doSomething() {
this.items.get(0)[0] = 1;
this.items.add(new short[] { 2, 2, 2 });
}
}
static class CopyListUser {
List<short[]> items;
CopyListUser(List<short[]> items) {
// CopyListUser copies the list, but both lists still share items
this.items = new LinkedList<short[]>(items);
}
void doSomething() {
this.items.get(0)[0] = 1;
this.items.add(new short[] { 2, 2, 2 });
}
}
static class DeepCopyUser {
List<short[]> items;
DeepCopyUser(List<short[]> items) {
// DeepCopyUser copies the list AND each entry
this.items = new LinkedList<short[]>();
for (short[] entry : items) {
this.items.add(Arrays.copyOf(entry, entry.length));
}
}
void doSomething() {
this.items.get(0)[0] = 1;
this.items.add(new short[] { 2, 2, 2 });
}
}
}
當DirectUser
使用的名單中,我們調用的代碼中,我們看到了雙方的名單變化(因爲它有更長的時間),並對其內容(第一:
這也許是最好的例子證明入口的第一個槽從0
更改爲1
)。
當CopyListUser
使用它時,它做了一個拷貝的列表,所以我們在調用代碼中沒有看到我們列表的任何變化(它沒有變長)。但我們確實看到更改爲第一項(因爲這兩個列表共享相同的陣列對象) —第一個插槽再次從0
更改爲1
。
當DeepCopyUser
使用它,它做了一個複製列表和每個條目的副本,這樣的事情是完全徹底的分離。我們的呼叫代碼沒有看到對列表或其項目的更改。
注:鏈表不是線程安全的。如果您在另一個線程中調用run(),則可能會看到或不會看到對集合所做的更改。 – 2012-04-17 11:45:05