代码之家  ›  专栏  ›  技术社区  ›  Dushmantha

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

  •  3
  • Dushmantha  · 技术社区  · 7 年前

    有什么更好的方法可以将List转换为varargs来调用builder(String。。。s)方法。

    builder( stringList.toArray( new String[stringList.size()] ) );//with pre-difined array size
    

    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()] ) ) .
    这两者有显著的区别吗? 谢谢

    4 回复  |  直到 7 年前
        1
  •  5
  •   Joop Eggen    7 年前

    据我所知

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

    更有效。原因:

    参数需要具有实际类型( String )对于泛型 List<String> ,其中泛型类型参数在运行时被删除。

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

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

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

    当然 list.size() 被称为额外的。所以可能会慢一些。我怀疑。


    修正

    Arrays of Wisdom of the Ancients . 正确的基准显示相反的情况: new String[0] 更快。 我刚刚把非常有趣的分析说得天花乱坠,似乎:

    • (特别短命的 新字符串[0] 无关紧要;)
    • 在toArray方法中执行数组本地复制允许不同的、更快的数组复制;
    • (然后还有一个额外的电话 size .)

    注意,这篇文章我读得不够透彻,真有趣。

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

    请注意:

    • 代码检查程序可能仍然会有不同的想法并发出警告;
    • 这就是热身:在hotspot JIT启动之前,可能是相反的情况。
        2
  •  2
  •   Eran    7 年前

    builder(stringList.toArray(new String[0])) 有点 较少的 高效,因为您创建了一个空数组,该数组将被丢弃,并且在方法返回后永不使用。 toArray 必须创建一个新数组才能存储 List .

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

        3
  •  2
  •   Eugene    7 年前

    有区别,主要是 by the Alexey Shipilev . 长话短说:

    toArray(新的T[0])看起来更快、更安全,而且在契约上更干净,因此现在应该是默认的选择

        4
  •  1
  •   Oleg Cherednik    7 年前

    我以为 c.toArray(new String[c.size()])) 更有效,因为我们在这里定义了一个具有所需大小的数组。

    但是!!

    智力观念 集合。toArray() 检查,默认情况下处于启用状态。这是描述:

    将集合转换为数组有两种样式:使用 预先确定大小的数组(例如 c、 toArray(新字符串[c.size()]) 或者使用 空数组(如 c、 toArray(新字符串[0]) .

    在旧的Java版本中 建议使用预先确定大小的数组作为反射调用 创建一个适当大小的数组是非常缓慢的。然而 由于OpenJDK 6的最新更新,这个调用被内在化,使得 空数组版本的性能相同,有时甚至 比预先定好的版本好。也通过预先设定的尺寸 数组对于作为 大小和toArray调用之间可能存在数据竞争,这可能 如果集合是 在手术中同时缩小。

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

    所以看起来,在JDK6之后,我们应该使用 c.toArray(new String[0]) . 我个人的看法是 这次用什么蟑螂都无所谓 . 只有当profiler说这是个瓶颈时,我们才应该担心它。