【问题标题】:Is there a method in the standard API which can deep clone a list?标准 API 中是否有可以深度克隆列表的方法?
【发布时间】:2015-03-26 15:40:33
【问题描述】:

大约 30 天后,我将参加 Java 竞赛。在比赛中,我们将获得一台装有 Eclipse 和 Java 1.7 API 的计算机。我正在练习上一年比赛的任务,我反复发现需要深度克隆一个列表。由于时间有限且只有 Java 1.7 API 可用,有没有办法做到这一点?

我已经看到了几种解决方案,包括

  • 实现Cloneable 接口。
  • 导入 Java 深度克隆库
  • List 所持有的任何对象的类实现一个克隆构造函数,并遍历元素。

但是这些解决方案要么在比赛中对我不可用,要么太耗时。现在,我需要深度克隆还包含ArrayLists 的对象的ArrayList

有谁知道这是否可能?感谢大家的帮助!

【问题讨论】:

  • 如何将对象序列化为流并再次返回? (他们是否实现可序列化)例如:avajava.com/tutorials/lessons/…
  • 你也想克隆元素吗?
  • 是的,我正在寻找一种方法来克隆 ArrayList 及其所有内容,以及内容的内容。
  • 如果你必须深度克隆,你也必须克隆集合中的元素。当然,为了做到这一点,元素也必须是可克隆的。

标签: java arraylist clone


【解决方案1】:

这将完全取决于列表中的内容。所以,简短的回答是:不。

您可以尝试序列化整个 List,但这要求 List 中的所有内容也都是可序列化的。您可以编写一个 deepClone() 方法,对 List 中的所有内容调用 clone() 方法,但这取决于 List 中的每个 Object 是否正确实现 clone() 方法。

这是一个竞赛问题的全部原因是没有一个快速的万能解决方案。

【讨论】:

    【解决方案2】:

    除了调用克隆之外,您还可以将所有内容写入 ByteArrayOutputStream 并再次读取。

    看看这是否对你有帮助:

      static public <T> T deepCopy(T oldObj) throws Exception {
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          oos = new ObjectOutputStream( bos);
          oos.writeObject( oldObj);
          oos.flush();
          ByteArrayInputStream bin = new ByteArrayInputStream( bos.toByteArray());
          ois = new ObjectInputStream( bin);
    
          return (T) ois.readObject();
        } catch( Exception e) {
          e.printStackTrace();
          throw ( e);
        } finally {
          if( oos != null) {
            oos.close();
          }
          if( ois != null) {
            ois.close();
          }
        }
      }
    

    用法 e。 g.:

    public class Testing {
    
      public static void main(String[] args) throws Exception {
    
        List<Object> list = new ArrayList<>();
        list.add( "A");
        list.add( "B");
        list.add( 1);
        list.add( 2);
        list.add( new BigDecimal( 123.456839572935879238579238754938741321321321321593857));
        list.add( new MyParentObject( 12345, "abcdef", new MyChildObject( "child")));
    
        List clone = (List) Tools.deepCopy( list);
    
        for( Object obj: clone) {
          System.out.println( obj);
        }
    
        System.exit(0);
      }
    
      private static class MyParentObject implements Serializable {
        int a;
        String b;
        MyChildObject child;
    
        public MyParentObject(int a, String b, MyChildObject child) {
          super();
          this.a = a;
          this.b = b;
          this.child = child;
        }
    
        public String toString() {
          return a + ", " + b + ", " + child;
        }
      }
    
      private static class MyChildObject implements Serializable {
        String s;
    
        public MyChildObject( String s) {
          this.s = s;
        }
    
        public String toString() {
          return s;
        }
      }
    }
    

    输出:

    A
    B
    1
    2
    123.456839572935876958581502549350261688232421875
    12345, abcdef, child
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-03
      • 2019-03-25
      • 2011-08-24
      • 1970-01-01
      • 2010-11-18
      • 2019-08-29
      • 2013-09-06
      • 1970-01-01
      相关资源
      最近更新 更多