简体   繁体   English

了解有效的Java深层复制示例

[英]Understanding Effective Java deep copy example

In Effective Java, 2nd Edition, Item 11 one can find the following deep copy example: 在有效的Java,第二版,第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();
        }
    }

I don't understand how this makes a deep copy: key and value are objects, therefore no primitive types. 我不明白这是如何进行深层复制的:键和值是对象,因此没有原始类型。 So to my understanding, using 因此,据我了解,

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

creates a new Entry with a reference to the key and value of the original Entry ? 创建一个新Entry ,并引用原始Entry的键和值?

Doesn't a deep copy basically mean: go down until one reaches primitive types, then copy those to the clone? 深度复制不是从本质上讲的意思:向下复制直到达到原始类型,然后将其复制到克隆中?

Thanks for any hint on this! 感谢您对此的任何提示!

It's a "deep copy" in that changes to the original object's linked list (via next ) will not be seen in the copy or vice versa. 这是一个“深层副本”,因为对原始对象链接列表的更改(通过next )将不会在副本中看到,反之亦然。 Compare that with the "shallow copy" which would be taken if the new object just copied the original next reference. 将其与“浅复制”进行比较,如果新对象刚刚复制了原始的next引用,则会进行“浅复制”。

It's a shallow copy in terms of the key and value though - if those are mutable types and are mutated then yes, the mutation will be seen via both the original and the "cloned" version. 不过,就键和值而言,它是一个浅表副本-如果它们是可变类型并且被突变,则是的,可以通过原始版本和“克隆”版本看到该突变。

So ultimately, it's a deeper copy than the naive "copy all references" approach - but it's not a fully deep copy. 因此,最终,它是比天真的“复制所有引用”方法更深的副本-但这不是完全深的副本。

When you create a deep copy, it is not enough to have the "same" entries in the new HashTable. 创建深层副本时,在新的HashTable中仅具有“相同”条目是不够的。 You must create new instances for each of those entries. 您必须为每个条目创建新实例 Otherwise, each table will hold a reference to the same entry object. 否则,每个表都将包含对相同条目对象的引用。 Then, when someone modifies a value in the first table, it will also be modified in the secon table (the new copy). 然后,当有人修改第一个表中的值时,该值也将在secon表(新副本)中被修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM