在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的数组中,因此必须在方法内部分配一个新数组,对吗?
那个音符是不正确的?或者还有其他意义吗?
答案 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])