将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 {}
。
两者之间有显着差异吗?
谢谢
答案 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]
无关紧要;)size
的额外呼叫。)注意,我没有足够详尽地阅读过这篇文章;真的很有趣。
结论(与直觉相反): new T[0]
更快。
记住:
答案 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])
。我个人的观点是,这次使用哪种多孔砂锅并不重要。仅当探查器说这是瓶颈时,我们才应该担心它。