传递零大小的数组,保存分配?

时间:2013-01-11 14:53:28

标签: java arrays garbage-collection

The Well-Grounded Java Developer第114页的代码示例中,最后一行:

Update[] updates = lu.toArray(new Update[0]);

包含注释:传递零大小的数组,保存分配

List<Update> lu = new ArrayList<Update>();
String text = "";
final Update.Builder ub = new Update.Builder();
final Author a = new Author("Tallulah");

for (int i=0; i<256; i++) {
  text = text + "X";
  long now = System.currentTimeMillis();
  lu.add(ub.author(a).updateText(text).createTime(now).build());
  try {
    Thread.sleep(1);
  } catch (InterruptedException e) {
  }
}

Collections.shuffle(lu);
Update[] updates = lu.toArray(new Update[0]);

这种节约的确切分配是什么?

List#toArray(T[] a)的javadoc提及:

  

如果列表适合指定的数组,则返回其中。   否则,将使用运行时类型分配新数组   指定的数组和此列表的大小。

我记得的是:如果传递给toArray(T[] a)的数组不能适合列表中的所有内容,则会分配一个新数组。显然,列表中有256个元素,不能放入大小为0的数组中,因此必须在方法内部分配一个新数组,对吗?

那个音符是不正确的?或者还有其他意义吗?

3 个答案:

答案 0 :(得分:3)

  

显然,列表中有256个元素,不能放入大小为0的数组中,因此必须在方法内部分配一个新数组,对吗?


您可以使用

 private static final Update NO_UPDATES = { }

 lu.toArray(NO_UPDATES);

然而,只有当您希望列表通常为0长度时,这才有用。

一般来说,我会采用与fge相同的方法

 lu.toArray(new Update[lu.size()]);

在您的具体情况下,您事先知道尺寸,以便做到

Update[] updates = new Update[256];
String text = "";
final Update.Builder ub = new Update.Builder();
final Author a = new Author("Tallulah");

long now = System.currentTimeMillis();
for (int i=0; i<updates.length; i++) 
  updates[i] = ub.author(a).updateText(text += 'X').createTime(now++).build();

Collections.shuffle(Arrays.asList(updates));

答案 1 :(得分:2)

关于@Andreas对这个问题的评论,我认为 是一个错字,应该说:

  

传递零大小的数组,安全分配。

因为如果你没有通过任何方法,你最终会调用List#toArray()无参数重载!

这将返回Object[](虽然它只包含Update个实例)并且需要更改updates变量的类型,因此最后一行将变为:

Object[] updates = lu.toArray();

然后每当你想迭代并使用该数组中的元素时,你必须将它们转换为Update

提供数组会调用List#toArray(T[] a)方法,该方法返回<T> T[]。这个数组被确定为知道它是Update个实例的数组。

因此,提供一个空的Updates数组会导致Update []从toArray调用返回,而不是Object []。这是一种更加类型 - 安全的分配! 注释中的“保存”一词必须是拼写错误!

......这消耗了过多的心理努力。将在书的论坛中发布链接,以便他们更正。

答案 2 :(得分:0)

toArray(new Update[255])toArray(new Update[1000])

相比,它可以节省分配