toArray List的方法,列表中包含对象的运行时类型

时间:2013-02-12 13:02:36

标签: java list toarray

使用javax.mail.Message#setRecipeints时,我第一次注意到了一件事,想要了解更多信息。

这是我的代码:

List<InternetAddress> ccRecipients = new ArrayList<InternetAddress>();
// have a valid and working 
// method that fills the list with the data (InternetAddress objects)
message.setRecipients(
         RecipientType.CC, ccRecipients.toArray(new InternetAddress[0]));

这里我不明白为什么我们要求创建一个新的InternetAddress数组并在toArray方法中将该元素传递给第0个索引?

任何人都可以解释为什么我们要求这样做?

我认为这与这种特殊的toArray方法有关。

我从API文档中读到以下内容,但没有得到最后一部分(粗体):

与toArray()方法类似,此方法充当基于数组的API和基于集合的API之间的桥梁。此外,此方法允许精确控制输出数组的运行时类型,并且在某些情况下可用于节省分配成本

如何节省分配成本?

4 个答案:

答案 0 :(得分:2)

不带参数的

toArray()会返回Object类型,但toArray(T[] a)会返回T[]的类型。这是List的通用方法。

答案 1 :(得分:0)

以下是您正在使用的ArrayList.toArray()方法的source

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

首先,你没有传入对索引0的引用,而是传递一个长度为0的新数组。假设你的列表不为空,那么新的零长度数组将太小而无法容纳它,并且是一个新的创建了正确类型的数组:Arrays.copyOf(elementData, size, a.getClass());

你可以传入一个足以容纳整个列表的数组,然后将列表复制到你提供的数组中:System.arraycopy(elementData, 0, a, 0, size);至于这是否会节省你的分配成本,很难说。 System.arraycopy()本机是一种方法,即依赖于平台。在没有看到它使用的代码的情况下,你只需要依赖这样一个事实,即本机实现通常应该更高效,并相信JVM编写者知道他们在做什么。

答案 2 :(得分:0)

该方法的参数是一个数组,如果它足够大,可以接收Collection的内容。我认为情况就是如果你已经分配了一个足够大的数组来保存集合,那么可以使用相同的数组而不是分配一个新数组。

请注意,您的代码传递的是一个长度为0的数组 - 只有在集合为空时才会返回该数组。如果List中有任何项目,将分配并返回一个新数组。

答案 3 :(得分:0)

要使用它来节省分配成本,数组参数必须至少与List一样长。在这种情况下,数据将复制到参数引用的数组中。假设List总是大小相同,您总是希望它是相同的元素类型,并且您一次只需要一个数组。您可以重用相同的数组,而不是每次调用toArray时都创建一个新数组。

实际上,每次创建一个新数组更为常见,但如果你使用List大小而不是0 toArray将能够使用它。