为了账号安全,请及时绑定邮箱和手机立即绑定

.toArray(new MyClass [0])或.toArray(new MyClass

.toArray(new MyClass [0])或.toArray(new MyClass

catspeake 2019-10-08 11:03:19
假设我有一个ArrayListArrayList<MyClass> myList;我想调用toArray,是否有使用性能的理由MyClass[] arr = myList.toArray(new MyClass[myList.size()]);过度MyClass[] arr = myList.toArray(new MyClass[0]);?我更喜欢第二种样式,因为它不太冗长,并且我假设编译器将确保不会真正创建空数组,但是我一直在想那是否是真的。当然,在99%的情况下,它不会以一种方式或其他方式产生任何差异,但是我想在我的普通代码和优化的内部循环之间保持一致的样式...
查看完整描述

3 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

从Java 5中的ArrayList开始,如果数组具有正确的大小(或更大),则将已填充该数组。所以


MyClass[] arr = myList.toArray(new MyClass[myList.size()]);

将创建一个数组对象,填充它并将其返回到“ arr”。另一方面


MyClass[] arr = myList.toArray(new MyClass[0]);

将创建两个数组。第二个是长度为0的MyClass数组。因此,有一个对象创建对象,该对象将立即被丢弃。就源代码而言,编译器/ JIT无法优化此代码,因此无法创建它。此外,使用零长度对象会导致toArray()方法中的转换。


请参见ArrayList.toArray()的来源:


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;

}

使用第一种方法,以便仅创建一个对象,并避免(隐式但仍然很昂贵)强制转换。


查看完整回答
反对 回复 2019-10-08
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

通过JetBrains Intellij Idea检查:


有两种样式可以将集合转换为数组:使用预大小数组(如c.toArray(new String [c.size()]))或使用空数组(如c.toArray(new String [ 0])。


在较早的Java版本中,建议使用预大小的数组,因为创建适当大小的数组所需的反射调用非常慢。但是,由于OpenJDK 6的更新较晚,因此此调用变得很有趣,与空大小版本相比,空数组版本的性能相同,有时甚至更好。同样,传递预大小的数组对于并发或同步收集也是危险的,因为在size和toArray 调用之间可能会发生数据争用 ,如果在操作期间同时缩小了集合,则在数组末尾可能会导致额外的null。


此检查允许遵循统一的样式:使用空数组(在现代Java中建议使用)或使用预定大小的数组(在较早的Java版本或基于非HotSpot的JVM中可能更快)。


查看完整回答
反对 回复 2019-10-08
  • 3 回答
  • 0 关注
  • 866 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信