【发布时间】:2016-11-07 15:26:59
【问题描述】:
为什么这个问题不是可能与How Arrays.asList(int[]) can return List<int[]>? 重复。 这个问题并没有真正回答我的特殊情况,因为我试图弄清楚我对 Arrays.copyOf 的使用是否存在差异。
CASE 1:假设是数组的深拷贝
// Creating a integer array, populating its values
int[] src = new int[2];
src[0] = 2;
src[1] = 3;
// Create a copy of the array
int [] dst= Arrays.copyOf(src,src.length);
Assert.assertArrayEquals(src, dst);
// Now change one element in the original
dst[0] = 4;
// Following line throws an exception, (which is expected) if the copy is a deep one
Assert.assertArrayEquals(src, dst);
案例 2: 这就是奇怪的地方: 我试图用下面的方法(从书中逐字提取)是创建输入数组参数副本的不可变列表视图。这样,如果输入数组发生变化,返回列表的内容不会改变。
@SafeVarargs
public static <T> List<T> list(T... t) {
return Collections.unmodifiableList(new ArrayList<>(Arrays.asList(Arrays.copyOf(t, t.length))));
}
int[] arr2 = new int[2];
arr2[0] = 2;
arr2[1] = 3;
// Create an unmodifiable list
List<int[]> list2 = list(arr2);
list2.stream().forEach(s -> System.out.println(Arrays.toString(s)));
// Prints [2, 3] as expected
arr2[0] = 3;
list2.stream().forEach(s -> System.out.println(Arrays.toString(s)));
// Prints [3, 3] which doesn't make sense to me... I would have thought it would print [2, 3] and not be affected by my changing the value of the element.
我看到的矛盾是,在一种情况下(案例 1), Arrays.copyOf 似乎是一个深拷贝,而在另一种情况下(案例 2),它似乎是一个浅拷贝。对原始数组的更改似乎已写入列表,即使我在创建不可修改列表时复制了数组。
有人能帮我解决这个差异吗?
【问题讨论】:
-
这里有很多问题。您将
int[]传递给 varargs 方法。它被包装成一个Object[],你将它传递给copyOf。因此,copyOf会复制包含单个int[]的Object[]。带有单个int[]的Object[]然后被包装成带有asList的List,只包含int[]。然后该列表中的元素(int[]被复制到一个新的ArrayList中。它一直是相同的int[]对象。 -
谢谢,Sotirios。如果我理解正确,正在复制的是 Object[](它包含 int[]),因此我实际上并没有制作我认为我正在传递给 list() 方法的 int[] 的副本。在第一种情况下,它是对 int[] 的直接操作,所以我看到的是对数组副本的更改。