列出具有预定尺寸或没有尺寸的varargs

Dus*_*tha 3 java arrays

将List转换为varargs以在"builder(String ... s)"方法下调用的更好方法是什么.

builder( stringList.toArray( new String[stringList.size()] ) );//with pre-difined array size
Run Code Online (Sandbox Code Playgroud)

要么

builder( stringList.toArray( new String[0] ) );//without predifined size
Run Code Online (Sandbox Code Playgroud)

例如

void test() {

  List<String> stringList = new ArrayList<>();
  builder( stringList.toArray( new String[stringList.size()] ) );//call builder method with pre-difining array size
  builder( stringList.toArray( new String[0] ) );//call builder method with array size 0

}

void builder( String... s )
{

}
Run Code Online (Sandbox Code Playgroud)

我在评论中遇到了这个问题,我被认为builder( stringList.toArray( new String[0] ) )比使用更有效builder( stringList.toArray( new String[stringList.size()] ) ).
这两者之间有显着差异吗?谢谢

Joo*_*gen 5

据我所知

stringList.toArray( new String[stringList.size()] ) )
Run Code Online (Sandbox Code Playgroud)

效率更高.原因:

该参数需要具有String泛型的实际type()List<String>,其中泛型类型参数在运行时被擦除.

如果结果数组与列表大小匹配,则该参数用于结果数组.

如果大小为0,则丢弃传递的数组.

因此传递正确的数组可以节省一个对象创建.

当然list.size()叫做额外的.所以它可能会变慢.我对此表示怀疑.


更正

参见古代智慧阵列.正确的基准显示逆:new String[0]更快.我刚刚通过这个非常有趣的分析,似乎:

  • (额外的短暂new String[0]无关紧要;)
  • 在toArray方法中进行数组复制本地允许一个不同的,更快的数组副本;
  • (然后有额外的电话size.)

记住,我没有充分阅读这篇文章; 这真的很有趣.

结论(反直觉):new T[0]更快.

请注意:

  • 代码检查员可能仍然以不同的方式思考并发出警告;
  • 这是热身:直到热点JIT开始,它可能是另一种方式.

  • 内部的toArray将再次调用list.size(),以检查大小,并可能创建自己的数组.因此,需要额外拨打一个电话.对于Java SE List实现,其中size是一个计数器字段,与`new String [0]`相比,开销是可忽略的.但是一些愚蠢的懒惰不可变链表实现可能没有这样的计数器维护,需要计算每个节点.但绝对不可能._我想我不应该提到它._ (2认同)