新しいノードを追加するときのLinkedListのシャローコピーは、変更を反映していません

ピーター・グエン:

ダイヤグラム私は読書の多くを行ったが、私はここに求めることなく、私の混乱をクリアすることができないように思えるしています。私がLinkedListの使用クローンのAA浅いコピーを作成する際に、図に基づいて()。新しいLinkedListのが作成され、オリジナルのヘッド変数の基準値は、クローンのにコピーされ、残りのノードが共有されています。私はクローンを使用して新しいノードを追加するのであれば、これをオリジナルのに表示されている必要がありそうではありませんか?値3からリスト1を印刷する場合でも、省略されています。なぜ誰かが私に言うことはできますか?

LinkedList<Integer> list1 = new LinkedList<>();
l1.add(1);
l1.add(2);
LinkedList<Integer> list2 = (LinkedList) l1.clone();
l2.add(3); 
マイケルZiober:

clone()新規作成されLinkedListた構造を第1のノードへの新しい参照を返します。これら二つの関係LinkedListのは、彼らが同じノードを共有していますvaluesあなたには、いくつか作るときadd\ remove古いまたは新しいリストの操作をこれらの操作は、他のリストは変更されません。我々がない理由はここにありcopy、我々はコピーを変更すると、元のリンクリスト構造を変更したくありません- 。

以下からのLinkedList.cloneドキュメント:

このの浅いコピーを返しますLinkedList要素自体は複製されません。)@return本の浅いコピーLinkedListインスタンスを

例の下に考えてみましょう:

import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;

public class LinkedListsApp {

    public static void main(String[] args) throws Exception {
        LinkedList<AtomicInteger> l1 = new LinkedList<>();
        l1.add(new AtomicInteger(100));
        l1.add(new AtomicInteger(200));

        LinkedList<AtomicInteger> l2 = (LinkedList) l1.clone();
        l2.add(new AtomicInteger(300));

        System.out.println(l1);
        System.out.println(l2);

        // change element on first list
        l1.get(0).incrementAndGet();

        System.out.println();
        System.out.println("After change internal state of first element");
        System.out.println(l1);
        System.out.println(l2);
    }
}

上記のコードを印刷:

[100, 200]
[100, 200, 300]

After change internal state of first element
[101, 200]
[101, 200, 300]

我々が見ることができるように、我々は最初のリストからの第1の要素の内部状態を変更するとき、それは同様に第二のリストのために表示されています。ノードと秩序のコピーを - ので、各要素値のない深いコピーではなく、構造体のコピーはありません。

それは絶対的に明確にするために、のがで実装に見てみましょうJava 8

public Object clone() {
    LinkedList<E> clone = superClone();

    // Put clone into "virgin" state
    clone.first = clone.last = null;
    clone.size = 0;
    clone.modCount = 0;

    // Initialize clone with our elements
    for (Node<E> x = first; x != null; x = x.next)
        clone.add(x.item);

    return clone;
}

上を見てくださいfor-eachループを。これは、元のリストを反復処理し、に値を追加するcloneリスト。この方法はadd、新規作成Node元のリストと同じ値を格納するオブジェクトを:x.item

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=181234&siteId=1