【问题标题】:Lists.newArrayList vs new ArrayListLists.newArrayList 与新的 ArrayList
【发布时间】:2012-04-16 09:04:34
【问题描述】:

创建List 字符串的最佳结构是什么?是Lists.newArrayList()(来自番石榴)还是new ArrayList()

这只是个人喜好吗?
还是只是类型泛型类型推断?
或者使用 Lists.newArrayList() 是否有任何理论或实践价值?

【问题讨论】:

标签: java generics guava


【解决方案1】:

guava builder 可以保存多次键入类型参数。比较:

List<Foo<Bar, Baz>> list = Lists.newArrayList();
List<Foo<Bar, Baz>> list = new ArrayList<Foo<Bar, Baz>>();

在 Java 7 中它有点过时了,因为你有菱形运算符:

List<Foo<Bar, Baz>> list = new ArrayList<>();

【讨论】:

  • 由于重载,它还没有完全过时 -- Lists.newArrayList(1, 2, 3) 允许您使用元素进行初始化,Lists.newArrayListWithExpectedSize(20) 使 20 的含义比 new ArrayList&lt;&gt;(20) 更明显。顺便说一句,这个问题的“官方答案”是here
  • 是的,但这是另一种方法。我的意思是没有参数的那个已经过时了。
  • 不管怎样,它还使呼叫站点不必导入ArrayList
  • 我总是只使用 List> list = new ArrayList();
  • @PaulBellora 而是在 Guavas Lists 上创建一个静态导入(因此不会减少导入,也不会失去对 ArrayList 的传递依赖,如果这是您的目标)。
【解决方案2】:

来自Guava's source

public static <E> ArrayList<E> newArrayList() {
    return new ArrayList<E>();
}

所做的只是允许类型推断 - 在运行时没有区别。

【讨论】:

    【解决方案3】:

    补充一点,重载版的Lists.newArrayList()更有用:

    • Lists.newArrayList(E... elements)
    • Lists.newArrayList(Iterable&lt;? extends E&gt; elements)
    • Lists.newArrayList(Iterator&lt;? extends E&gt; elements)

    提供比new ArrayList()更多有用的功能。

    例如:new ArrayList() 不能做:

    Lists.newArrayList("a","b");
    Lists.newArrayList(anIterable);
    

    【讨论】:

      【解决方案4】:

      这就是 Lists.newArrayList 的作用:

      @GwtCompatible(serializable = true)
      public static <E> ArrayList<E> newArrayList() {
          return new ArrayList<E>();
      }
      

      所以这两个基本相同,使用 newArrayList 的优点是不必复制泛型类型。这对复杂的泛型很有帮助:

      List<Map<X,List<Y>> list = new ArrayList<Map<X,List<Y>>();
      
      List<Map<X,List<Y>> list = Lists.newArrayList();
      

      【讨论】:

      • 根据方法签名使用 Guava 的完整方法调用将是 Lists.&lt;Map&lt;X,List&lt;YY&gt;&gt;&gt;newArrayList()。您可以省略泛型类型。但是您也可以使用构造函数来执行此操作:List&lt;Map&lt;X,List&lt;Y&gt;&gt;&gt; list = new ArrayList(); 也可以。
      【解决方案5】:

      正如here 所解释的,使用ListsSets 等的主要动机是提高代码的可读性/重复性以及类型推断。

      【讨论】:

        【解决方案6】:

        用于重载构造函数的 Java 8 方法。

        如果您想使用来自 Guava 的重载构造函数,我会推荐另一种使用 Java 8 Stream Builder 的方式。

        List<String> listTest = Stream.<String>builder
        .add("Hello").add("My Name").add("Blah")
        .build().collect(Collectors.toList());
        

        如果您使用的是 Java 版本 9+,则可以在下面使用。但是此方法返回一个 ImmutableList,因此您无法向其中添加更多元素。

        List.of("My","Name", "IS", "this");
        

        【讨论】:

        • 为什么推荐这个? (另外,为什么不Stream.of("Hello", "My Name", "Blah")?)
        • @aioobe - 这也有效,但前提是您在一行中拥有所有可用的元素,更像是声明或硬编码值。但是,如果您必须迭代值才能创建新列表,那么 Stream Builder 将是更好的选择。
        【解决方案7】:

        如前所述,Java 7 已经过时了,但我使用工厂方法,因为它使更改列表、集合、映射或其他任何东西的类型变得更容易。

        【讨论】:

          【解决方案8】:

          你可以从java.util 使用Arrays.asList(),这样你就不必使用番石榴了:

          List<String> list = Arrays.asList("one","another", null, "one_more")
          

          (顺便说一句,Java 8 中的 Stream Builder 也是一种选择,但对于大多数常见用例而言,它过于冗长和过度杀伤)

          【讨论】:

            猜你喜欢
            • 2016-11-08
            • 2015-12-10
            • 1970-01-01
            • 1970-01-01
            • 2013-04-21
            • 2014-12-07
            • 1970-01-01
            • 2021-07-22
            • 2011-08-16
            相关资源
            最近更新 更多