代码之家  ›  专栏  ›  技术社区  ›  Bill the Lizard

如何在Java中克隆通用列表?

  •  142
  • Bill the Lizard  · 技术社区  · 16 年前

    我有一个 ArrayList<String> 我想退一份。 ArrayList 具有具有以下签名的克隆方法:

    public Object clone()
    

    调用此方法后,如何将返回的对象强制转换回 数组列表<字符串> ?

    14 回复  |  直到 16 年前
        1
  •  54
  •   Vinko Vrsalovic    16 年前
    ArrayList newArrayList = (ArrayList) oldArrayList.clone();
    
        2
  •  296
  •   Tom Hawtin - tackline    9 年前

    为什么要克隆?创建新列表通常更有意义。

    List<String> strs;
    ...
    List<String> newStrs = new ArrayList<>(strs);
    

    工作完成了。

        3
  •  20
  •   Aracem    9 年前

    我使用的代码是:

    ArrayList copy = new ArrayList (original.size());
    Collections.copy(copy, original);
    

    希望对你有用

        4
  •  17
  •   Simon Jenkins    9 年前

    使用Java 8,它可以用流克隆。

    import static java.util.stream.Collectors.toList;
    

    List<AnObject> clone = myList.stream().collect(toList());
    
        5
  •  16
  •   Julien Chastang    16 年前

    请注意,object.clone()存在一些主要问题,在大多数情况下不鼓励使用它。请参阅第11项,来自“ Effective Java “乔舒亚·布洛克给出了一个完整的答案。我相信您可以在基元类型数组上安全地使用object.clone(),但除此之外,您还需要明智地正确使用和覆盖clone。您最好定义一个复制构造函数或一个静态工厂方法,该方法根据您的语义显式地克隆对象。

        6
  •  14
  •   Aaron    16 年前

    我认为使用集合API应该可以做到这一点:

    注释 :复制方法以线性时间运行。

    //assume oldList exists and has data in it.
    List<String> newList = new ArrayList<String>();
    Collections.copy(newList, oldList);
    
        7
  •  6
  •   Uri Shalit    9 年前

    如果您希望此操作能够在getter中返回列表,则最好执行以下操作:

    ImmutableList.copyOf(list);
    
        8
  •  6
  •   Jonathan Precise Azhar    6 年前

    我发现使用addall很好。

    ArrayList<String> copy = new ArrayList<String>();
    copy.addAll(original);
    

    使用括号而不是泛型语法

        9
  •  3
  •   Ahmed Hamdy    9 年前

    克隆通用接口 java.util.List 你只需要铸造它。下面是一个例子:

    List list = new ArrayList();
    List list2 = ((List) ( (ArrayList) list).clone());
    

    这有点棘手,但如果您只能返回 List 接口,这样任何人在您之后都可以随时实现您的列表。

    我知道这个答案接近最终的答案,但我的答案回答了当你在工作时如何做所有这些 -通用父级-非 ArrayList

        10
  •  2
  •   Juan Besa    16 年前

    克隆数组列表时要非常小心。在Java中克隆是很浅的。这意味着它将只克隆ArrayList本身,而不克隆它的成员。因此,如果您有一个arraylist x1并将其克隆到x2中,x2中的任何更改也将在x1中显示,反之亦然。克隆时,将只生成一个新的ArrayList,其中包含指向原始元素中相同元素的指针。

        11
  •  2
  •   user2627846    9 年前

    这也应该有效:

    ArrayList<String> orig = new ArrayList<String>();
    ArrayList<String> copy = (ArrayList<String>) orig.clone()
    
        12
  •  1
  •   jodonnell    16 年前
    ArrayList first = new ArrayList ();
    ArrayList copy = (ArrayList) first.clone ();
    
        13
  •  1
  •   Petr    13 年前

    我不是Java专业人士,但我有同样的问题,我试图用这种方法解决。(假设t有一个复制构造函数)。

     public static <T extends Object> List<T> clone(List<T> list) {
          try {
               List<T> c = list.getClass().newInstance();
               for(T t: list) {
                 T copy = (T) t.getClass().getDeclaredConstructor(t.getclass()).newInstance(t);
                 c.add(copy);
               }
               return c;
          } catch(Exception e) {
               throw new RuntimeException("List cloning unsupported",e);
          }
    }
    
        14
  •  0
  •   Robert    6 年前
    List<String> shallowClonedList = new ArrayList<>(listOfStrings);
    

    请记住,这只是一个浅薄而不是深刻的副本,即你得到了一个新的列表,但条目是相同的。对于简单的字符串来说,这不是问题。当列表项是自己的对象时,get更难处理。