2009-04-07 77 views
6

如果你有一个集合的实例,这样说:什么传递给数组实例方法toArray(T [] a)方法?

Collection<String> addresses = new ArrayList<String>(); 

这当中,然后被一帮价值观,这是“最好”的方式,如果有的话,尽量使用的填充toArray()方法而不需要类型转换?

String[] addressesArray = addresses.toArray(new String[] {}); 
String[] addressesArray = addresses.toArray(new String[0]); 
String[] addressesArray = addresses.toArray(new String[addresses.size()]); 
String[] addressesArray = addresses.toArray(new String[addresses.size() + 5]); 

前两者之间是否有语义上的区别?第三最有效率?第四个效率低于第三个?

回答

7

根据a findbugs report,这是最有效的:

String[] addressesArray = addresses.toArray(new String[addresses.size()]); 

我相信他们;)

+2

这是不正确的,根据@AlekseyShipilev http://shipilev.net/blog/2016/arrays-wisdom-ancients/ – 2016-02-19 20:21:26

0

这在List界面的Javadoc被记载:

如果列表适合与空间指定的阵列中剩余空间(即,该阵列具有比列表多个元件),该元件阵列中的紧随列表结尾后立即设置为空。 (这是在确定只有当呼叫方知道列表不包含任何空元素的列表的长度是有用的。)

+0

它是有道理的,如果ArrayList的大小是5,并且您传递给Array()一个新的大小为10的String数组,那么它将被调整大小,但我仍然不知道哪个或多或少是正确/高效的。 – 2009-04-07 21:25:58

+0

它不调整数组的大小,它只是将列表末尾的元素设置为null。 – 2009-04-07 21:38:29

0

你对前两条语句的效果是一样的。

第三个是最有效的,因为如果你的元素不适合数组,你会为你创建一个新的数组。

3

如果您选择不相信他人,或者只是想自己检查,您可以查看source for java.util.ArrayList(张贴该来源可能违反了一些许可证,我很高兴我只是链接到它)。当您下载Sun's JDK时,您还可以获得所有源代码的副本)。

审查源代码<T> T[] toArray(T[] a);后很明显:

String[] addressesArray = addresses.toArray(new String[addresses.size()]); 

是做到这一点的最快方式。

显然,你不能总是花时间阅读和理解源代码,有时最好的选择并不总是显而易见的,但是对于更简单的方法,阅读源代码可能非常有用。

5

对于我的钱

String[] addressesArray = addresses.toArray(new String[0]); 

是最简单的,容易出错最少,因此 “最好的”。它还具有相同的代码适用于并发/同步集合的优点。你将不得不在一些真正的低级别,大量使用的代码中忽略不计的性能差异来产生任何影响。

你经常看到分配给static final,以避免在每次执行分配一个空数组。显然,事实证明,由于“优化”(配置确实非常快),性能会下降。

更新:转出,这是比使用大小的数组更快。http://shipilev.net/blog/2016/arrays-wisdom-ancients/tl; dr:反射是不涉及慢方法查找的普通类型,如果可以确定所有元素都将被写入(或数组变为不可访问),则可以丢弃数组的零点。

+2

+1的文章发现并发问题。我曾经在代码中遇到过这个问题:http://github.com/orfjackal/dimdwarf/blob/0d1a0897821a4e0e557a1390a7252a8580d2ec95/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/scheduler/TaskThreadPool.java#L111 -116 – 2009-04-08 14:27:57

1

这主要是理论上的意义,但如果该列表是空的时候,你可以重用一个长度为零的数组:

private static final String[] EMPTY_STRING_ARRAY = {}; 
... 
String[] addressesArray = addresses.toArray(EMPTY_STRING_ARRAY); 

由于零长度数组是不可变的(不像非零长度数组),它们可以存储并重用。