run() 内の dataList を変更すると、別の場所で宣言されている元のリストに変更が反映されますか?
はい。コンストラクターは、リストのコピーではなく、リストへの参照を受け取ります。コピーする場合は、LinkedList
コピー コンストラクターを使用する必要があります。次に、リストの独自のコピーを作成します。ただし、エントリは配列 ( ) であり、配列は参照によって格納されるため、2 つのリストのエントリは引き続き共有されることに注意してください。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
を使用すると、リストのコピーと各エントリのコピーが作成されるため、物事は完全に完全に切断されました。リストまたはその項目への変更は、呼び出しコードによって確認されませんでした。