java list.toArray 方法?

        List<Integer> list = List.of(12, 34, 56);

Integer[] array = list.toArray(new Integer[]{1, 2, 1, 43, 32, 1});

System.out.println(Arrays.toString(array));

输出: [12, 34, 56, null, 32, 1]


不应该是: [12, 34, 56, null, null, null] 吗?
这是为什么?
版本:GraalVM for JDK 17


回答:

看一下toArray方法的源码文档:

* If the list fits in the specified array with room to spare (i.e.,

* the array has more elements than the list), the element in the array

* immediately following the end of the list is set to <tt>null</tt>.

* (This is useful in determining the length of the list <i>only</i> if

* the caller knows that the list does not contain any null elements.)

意思就是如果数组的元素比列表多,数组中紧跟在列表末尾后面那一位置的元素设置为null,
如果调用者知道列表不包含任何null元素的情况下,方便推断得出列表的真实长度
以ArrayList为例,它的实现如下:

@SuppressWarnings("unchecked")

public <T> T[] toArray(T[] a) {

if (a.length < size)

// Make a new array of a's runtime type, but my contents:

return (T[]) Arrays.copyOf(elementData, size, a.getClass());

System.arraycopy(elementData, 0, a, 0, size);

if (a.length > size)//如果数组的长度大于列表,把列表后面的第一个位置置为null

a[size] = null;

return a;

}

你题目里这个of生成的应该是一个UnmodifiableList? 它的实现也差不多,总之也是只把紧跟着列表后面的那个元素置为null:

@SuppressWarnings("unchecked")

public <T> T[] toArray(T[] a) {

// We don't pass a to c.toArray, to avoid window of

// vulnerability wherein an unscrupulous multithreaded client

// could get his hands on raw (unwrapped) Entries from c.

Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));

for (int i=0; i<arr.length; i++)

arr[i] = new UnmodifiableEntry<>((Map.Entry<? extends K, ? extends V>)arr[i]);

if (arr.length > a.length)

return (T[])arr;

System.arraycopy(arr, 0, a, 0, arr.length);

if (a.length > arr.length)

a[arr.length] = null;//看这里看这里

return a;

}


回答:

这个问题看java的源代码就好,主要不理解的应该就是
Integer[] array = list.toArray(new Integer[]{1, 2, 1, 43, 32, 1});
这行代码。我本地是jdk8的环境,但是运行结果是一样,进入ArrayList源码中

 public <T> T[] toArray(T[] a) {

if (a.length < size)

// Make a new array of a's runtime type, but my contents:

return (T[]) Arrays.copyOf(elementData, size, a.getClass());

System.arraycopy(elementData, 0, a, 0, size);

if (a.length > size)

a[size] = null;

return a;

}

可以看到,a的长度如果比list长度小,就返回list的数组形式。
如果a的长度比list长度长,就把list的元素拷贝到a的指定位置,因为a的超长部分已经有值了,所以是二者的组合
最后可能为了分割吧,把list结尾换成了个null。

写代码组合的时候不建议用这么不好理解的Api。而且碰到问题看源码即可

以上是 java list.toArray 方法? 的全部内容, 来源链接: utcz.com/p/945369.html

回到顶部