Java构建没有深度克隆的新ArrayList

时间:2013-10-14 07:15:06

标签: java arraylist

我有一个关于根据现有列表构建新ArrayList的问题,我需要它来反转List。我不需要深度克隆元素,因为我只检查它们的值而不更改它们。

我的旧的,有效的代码,对我来说似乎有些惹人注意,所以我觉得我以前遇到过这个问题:

        Collections.sort(invoiceWordGroups, new WordGroup.WordGroupComparator());
        insertAttributes(topAttributeWords, invoiceWordGroups, templateId, templateAttributeManager, invoiceMarginDataVAT);
        Collections.reverse(invoiceWordGroups);
        insertAttributes(bottomAttributeWords, invoiceWordGroups, templateId, templateAttributeManager, invoiceMarginDataVAT);

我的新代码,我会测试它,但即便如此,如果我的基本概念不是oK,那么一些错误可能会留在那里。那么这会有相同的行为吗?

        Collections.sort(invoiceWordGroups, new WordGroup.WordGroupComparator());
        List<WordGroup> invoiceWordGroupsReverse = new ArrayList<>(invoiceWordGroups);
        Collections.reverse(invoiceWordGroupsReverse);
        insertAttributes(topAttributeWords, invoiceWordGroups, templateId, templateAttributeManager, invoiceMarginDataVAT);
        insertAttributes(bottomAttributeWords, invoiceWordGroupsReverse, templateId, templateAttributeManager, invoiceMarginDataVAT);

问题是关于invoiceWordGroupsList<WordGroup>类型。我改变它的原因是因为我现在需要多次使用这些列表,并且不断地反转它确实不是一个好的选择。

1 个答案:

答案 0 :(得分:3)

如果检查Java源代码,ArrayList的复制构造函数会创建一个新的列表对象,它复制(因此名称为复制构造函数)内部数组(但即使它是原始数组的副本,它仍然指向相同的元素!!!)。这个内部数组对象因此不是共享的,它是负责给定列表对象实际存储的对象以及以什么顺序存在的对象:

   public ArrayList(Collection<? extends E> c) {
       elementData = c.toArray();
       size = elementData.length;
       // c.toArray might (incorrectly) not return Object[] (see 6260652)
       if (elementData.getClass() != Object[].class)
           elementData = Arrays.copyOf(elementData, size, Object[].class);
   }

因此,反转一个列表将不会影响另一个列表的顺序。从一个列表或另一个列表添加/删除元素也是如此。

你说这些是只读对象然后就可以了但是请记住,即使两个列表都是不同的对象,它们仍然指向相同的元素,所以改变对象X的状态使用list2访问该对象X时也会显示list1。