7

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 的数组中,因此必须在方法内部分配一个新数组,对吗?

那么这个注释不正确吗?或者还有别的意思吗?

4

3 回答 3

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));
于 2013-01-11T15:02:10.637 回答
2

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

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

因为如果你什么都不传递给方法,你最终会调用List#toArray()无参数重载!

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

Object[] updates = lu.toArray();

然后每次您想要迭代并使用该数组中的元素时,您都必须将它们强制转换为Update.

提供数组调用List#toArray(T[] a)方法,该方法返回一个<T> T[]. 这个数组被具体化以知道它是一个Update实例数组。

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

...这消耗了太多的脑力劳动。将在本书的论坛中发布此链接,以便他们进行更正。

于 2013-01-11T19:03:39.490 回答
0

它节省了分配,比较toArray(new Update[255])toArray(new Update[1000])

于 2013-01-11T15:15:01.917 回答