列出具有预定义大小或没有大小的varargs

时间:2018-08-09 12:07:37

标签: java arrays

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

builder( stringList.toArray( new String[0] ) );//without predifined size

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 )
{

}

例如

builder( stringList.toArray( new String[0] ) )

我在一次评论中遇到了这个问题,并建议builder( stringList.toArray( new String[stringList.size()] ) )比 使用.abc {}
两者之间有显着差异吗? 谢谢

4 个答案:

答案 0 :(得分:5)

据我了解

stringList.toArray( new String[stringList.size()] ) )

更有效率。原因:

对于通用String,该参数必须具有实际类型(List<String>),其中通用类型参数在运行时被删除。

如果参数的大小与列表大小匹配,则将其用于结果数组。

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

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

当然list.size()被称为多余。因此,它可能会更慢。我对此表示怀疑。


更正

请参见Arrays of Wisdom of the Ancients。 正确的基准显示相反的结果:new String[0]更快。 我只是跳过了非常有趣的分析,似乎:

  • (寿命短的new String[0]无关紧要;)
  • 在toArray方法中进行本地数组复制可以实现不同的,更快的数组复制;
  • (然后是对size的额外呼叫。)

注意,我没有足够详尽地阅读过这篇文章;真的很有趣。

结论(与直觉相反): new T[0]更快。

记住:

  • 代码检查器可能仍会有所不同并发出警告;
  • 这伴随着热身:在热点JIT出现之前,情况可能恰恰相反。

答案 1 :(得分:2)

builder(stringList.toArray(new String[0]))的效率稍差 ,因为您创建了一个空数组,该数组将在方法返回后被丢弃且从不使用。 toArray必须创建一个新数组才能存储List的元素。

另一方面,builder(stringList.toArray(new String[stringList.size()]))将具有所需长度的数组传递给toArray方法,因此该方法将使用该数组而不是创建新数组。

答案 2 :(得分:2)

有所不同,主要概述为by the Alexey Shipilev。长话短说:

  

toArray(new T [0])看起来更快,更安全且从合约上讲更干净,因此现在应该是默认选择

答案 3 :(得分:1)

我认为c.toArray(new String[c.size()]))效率更高,因为我们在此处定义了所需大小的数组。

但是!

IntelliJ IDEA 具有 Collection.toArray()检查,默认情况下处于启用状态。这是描述:

  

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

     

在较旧的Java版本中   建议使用预大小的数组,因为反射调用是   创建适当大小的数组所必需的速度非常慢。然而   自从OpenJDK 6的最新更新以来,此调用引起了人们的注意,   空数组版本的性能相同,有时甚至   比预大小版本更好。还通过了预尺寸   数组对于并发或同步集合是危险的,因为   在size和toArray调用之间可能发生数据争夺   如果集合是,则在数组末尾产生额外的null   在手术过程中同时缩小。

     

此检查允许遵循统一的样式:   空数组(在现代Java中推荐)或使用预先设置的大小   数组(在较旧的Java版本或非HotSpot中可能更快   基于JVM的系统。

因此,似乎在JDK6之后,我们应该使用c.toArray(new String[0])。我个人的观点是,这次使用哪种多孔砂锅并不重要。仅当探查器说这是瓶颈时,我们才应该担心它。