【问题标题】:Java list which clones elements when added添加时克隆元素的 Java 列表
【发布时间】:2019-06-03 16:26:46
【问题描述】:

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

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

【问题讨论】:

    标签: java list class encapsulation


    【解决方案1】:

    我怀疑一个存在,有几个原因:

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

    【讨论】:

      【解决方案2】:

      没有标准的方法来实现任何 Collection,在添加对象时自动克隆其对象。

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

      还可以选择不在列表中实际存储可变数据。您始终可以创建要存储在 Collection 中的数据的不可变实现。如果可能的话,这是我会选择的选项。如果你走这条路,你仍然必须确保 Data 元素是不可变的,或者有一个 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 接口带来的所有问题,您可以创建自己的接口,该接口更适合您的应用程序。

      【讨论】:

        猜你喜欢
        • 2011-02-12
        • 2012-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-22
        • 2011-11-27
        • 2010-09-08
        • 1970-01-01
        相关资源
        最近更新 更多