我有一个关于根据现有列表构建新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);
问题是关于invoiceWordGroups
,List<WordGroup>
类型。我改变它的原因是因为我现在需要多次使用这些列表,并且不断地反转它确实不是一个好的选择。
答案 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。