Java 添加时克隆元素的列表

Java list which clones elements when added

是否有Java class 实现了List 接口并在将元素添加到列表时克隆元素?这样做的目的是将此列表封装为一个对象。

当然,我自己写一个很容易,比如,将 ArrayList 包装在另一个 class 中,然后在实现 add 和 get 方法时调用 clone 方法。但是,我想我会问 Java 是否已经提供了这样的 class 并且可能会为自己节省一些繁琐的编码。

我怀疑是否存在,原因如下:

  1. 应该如何列出克隆元素? Object.clone() 仅适用于实现 @Cloneable 的类型;当它工作时,它只制作一个浅拷贝(例如,如果对象有一个 List 字段,它会克隆对列表对象的引用,而不是它的元素);打败它自己的目的。 Info about Java cloning problems。因此,要使克隆真正起作用,可克隆类型需要使用适当的实现来覆盖 Object.clone() 。这意味着您的 "cloning list" 需要知道包含的类型是否正确地实现了 clone(),即使它成功实现了,它也只对一组非常有限的类型有用。
  2. 对于实际实现 clone() 的类型,执行 list.add(elem.clone()) 而不是 list.add(elem) 相当简单。一种全新的列表类型,带有第 1 点中提到的注意事项,只是为了让我们免于输入 8 个字符,这似乎不是一个很有用的东西。

没有任何标准方法可以实现任何在添加对象时自动克隆其对象的集合。

如果您确实愿意,可以创建自己的 List 实现并 use reflection 克隆每个进出的对象。当被问到这样的问题时,我从不建议您实际在 Collections 库中创建自己的实现。我认为在这种情况下实际创建自己的实现的唯一原因是,如果您有其他一些库将 List 或 Collection 作为参数,并且您真的不希望该 Collection 的值发生变化。

还可以选择不实际将可变数据存储在列表中。您始终可以为要存储在集合中的数据创建不可变的实现。如果可能的话,这是我会选择的选项。如果你走这条路,你仍然必须确保数据元素是不可变的,或者用 List<ImmutableData> 代替。使用 List<ImmutableData> 可能不是一个坏主意,但您可能必须在大多数方法签名中使用 List<? extends Data>

它可能看起来像这样:

interface Data {
    String getString();
    MutableData toMutable();
}
class MutableData implements Data {
    String getString() {...}
    void setString(String s) {...}
    Data toImmutable() {...}
    MutableData clone() {...}
}
class ImmutableData implements Data {...}

如果您仍然想要克隆,但不想使用反射或处理 Cloneable 接口带来的所有问题,您可以创建自己的接口,该接口更适合您的应用程序。