1

『Effective Java, 2nd Edition, Item 11』では、次のディープ コピーの例を見つけることができます。

public class HashTable implements Cloneable {
    private Entry[] buckets = ...;

    private static class Entry {
        final Object key;
        Object value;
        Entry next;
        Entry(Object key, Object value, Entry next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }

        // Recursively copy the linked list headed by this Entry
        Entry deepCopy() {
            return new Entry(key, value,
                    next == null ? null : next.deepCopy());
        }
    }
    @Override public HashTable clone() {
        try {
            HashTable result = (HashTable) super.clone();
            result.buckets = new Entry[buckets.length];
            for (int i = 0; i < buckets.length; i++)
                if (buckets[i] != null)
                    result.buckets[i] = buckets[i].deepCopy();
            return result;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

これがどのようにディープ コピーを作成するのか理解できません。キーと値はオブジェクトであるため、プリミティブ型はありません。だから私の理解では、

// Recursively copy the linked list headed by this Entry
Entry deepCopy() {
    return new Entry(key, value,
            next == null ? null : next.deepCopy());
}

Entry元のキーと値への参照を使用して新しいを作成しEntryますか?

ディープ コピーとは基本的に、プリミティブ型に到達するまで下に移動し、それらをクローンにコピーすることを意味するのではないでしょうか?

これに関するヒントをありがとう!

4

2 に答える 2

5

元のオブジェクトのリンク リストへの変更 ( 経由next) がコピーに表示されないという点で、これは "ディープ コピー" であり、その逆も同様です。nextそれを、新しいオブジェクトが元の参照をコピーしたばかりの場合に取得される「浅いコピー」と比較してください。

ただし、キーと値に関しては浅いコピーです。それらが変更可能な型であり、変更されている場合、変更は元のバージョンと「複製された」バージョンの両方で見られます。

したがって、最終的には、単純な「すべての参照をコピーする」アプローチよりも深いコピーになりますが、完全に深いコピーではありません。

于 2013-03-29T21:41:40.530 に答える
1

ディープ コピーを作成する場合、新しい HashTable に「同じ」エントリを含めるだけでは十分ではありません。これらのエントリごとに新しいインスタンスを作成する必要があります。それ以外の場合、各テーブルは同じエントリ オブジェクトへの参照を保持します。次に、誰かが最初のテーブルの値を変更すると、2 番目のテーブル (新しいコピー) でも変更されます。

于 2013-03-29T21:43:26.550 に答える