0

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

我的旧代码,工作代码,对我来说似乎有点骇人听闻,所以我认为我过去遇到过问题:

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

我的新代码,我当然也会对其进行测试,但即便如此,如果我的基本概念不正确,一些错误可能仍然存在。那么这会有相同的行为吗?

        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);

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

4

1 回答 1

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 时,也会显示在 list1 中更改对象 X 的状态与list2。

于 2013-10-14T07:38:27.147 回答