【问题标题】:How to quickly and conveniently create a one element arraylist [duplicate]如何快速方便地创建一个元素数组列表 [重复]
【发布时间】:2013-12-19 23:11:51
【问题描述】:

是否有一个实用方法可以在 1 行中执行此操作?我在CollectionsList 的任何地方都找不到它。

public List<String> stringToOneElementList(String s) {
    List<String> list = new ArrayList<String>();
    list.add(s);
    return list;
}

我不想重新发明轮子,除非我打算在轮子上装上花哨的轮辋。

嗯...类型可以是T,而不是String。但你明白了。 (包括所有空值检查、安全检查等)

【问题讨论】:

  • 好吧,你根本不应该使用那种方法。调用方法的地方,把调用替换成你要找的“单行”变换即可。
  • 我的意思是,您想将方法内的所有内容都转换为一行,对吗?好吧,那么这种方法实际上并没有做任何没有它就无法完成的事情。你会做的是,return Arrays.asList(s);。但是那个额外的方法有什么意义呢?它只是充当代表。只需将其删除。无论你打电话给stringToOneElementList(s),还是打电话给Arrays.asList(s),就是这样。
  • 哦,好吧,我想我明白了。好吧,我有这种方法的唯一原因是因为我不知道“神奇的一班轮”在哪里。因此,这就是为什么我首先问了这个 stackoverflow 问题。如果我已经知道那一行Arrays.asList(s),那我为什么要在stackoverflow上问我的问题?我惊讶地发现这种方便的方法是在数组中而不是在集合中。
  • Arrays 是一个实用程序类,其中包含您可能不时使用的各种其他方法。之所以在Arrays 类中使用此方法,是因为该方法实际上是从array 转换为list。该方法被定义为采用 var-args。因此,您传递给它的任何参数都仅在内部转换为数组。然后从中创建一个列表。所以,这是它指定的地方 - Arrays
  • Java 的设计是将任意数量的字符串转换为列表,其中仅包含 1 个字符串(但也意味着只有一种方法可以这样做)。在其他语言中,做某事的方法不止一种,所以我只想知道最好的方法(在这种情况下,只有一种方法),例如,ruby,你可以说“blah.first”和“blah.last” " 而不是像 "blah[0]" ,它非常方便且更具可读性。在 Java 中,情况似乎并非如此。对不起,希望这是有道理的

标签: java arraylist collections


【解决方案1】:

固定大小List

据我所知,最简单的方法是创建一个固定大小的单个元素 ListArrays.asList(T...) 类似

// Returns a List backed by a varargs T.
return Arrays.asList(s);

可变大小List

如果它需要不同的大小,您可以构造一个ArrayList 和固定大小的List 之类的

return new ArrayList<String>(Arrays.asList(s));

并且(在 Java 7+ 中)您可以使用 diamond operator &lt;&gt; 来制作它

return new ArrayList<>(Arrays.asList(s));

单元素列表

集合可以返回一个包含单个元素的列表,其中列表是不可变的:

Collections.singletonList(s)

这里的好处是 IDE 代码分析不会警告单个元素 asList(..) 调用。

【讨论】:

  • 这正是我想要的。谢谢!我不知道为什么这是在数组中,而不是在列表中,或者在集合中。
  • 小心这个解决方案。您不能修改列表。例如,如果您尝试向此列表添加元素,它将抛出 UnsupportedOperationException!
  • Collections.singletonList(elm);更可取,因为它创建了不可变列表。
  • @RavishBhagdev - 并非总是如此。有时您可能希望稍后将内容添加到列表中。事实上,我在图中的寻路算法中正是使用了这个答案的方法。
  • 从 JDK9 开始,将有一个方法 List.of​(E e1) 返回一个不可变列表 (download.java.net/java/jdk9/docs/api/java/util/List.html#of-E-)
【解决方案2】:
Collections.singletonList(object)

此方法创建的列表是不可变的。

【讨论】:

  • IntelliJ IDEA 自动推荐这个而不是 Arrays.asList(object)
  • 注意这个方法创建的列表是不可变的。
  • 所以你没有花时间写一行这个电话的后果?不可变列表
  • 请将此标记为已接受的答案。这比 Arrays.asList 好得多。
【解决方案3】:

您可以使用实用方法Arrays.asList 并将结果输入新的ArrayList

List<String> list = new ArrayList<String>(Arrays.asList(s));

其他选项:

List<String> list = new ArrayList<String>(Collections.nCopies(1, s));

List<String> list = new ArrayList<String>(Collections.singletonList(s));

在 Java 7+ 中,您可以使用“菱形运算符”,将 new ArrayList&lt;String&gt;(...) 替换为 new ArrayList&lt;&gt;(...)

Java 9

如果您使用的是 Java 9+,则可以使用 List.of method

List<String> list = new ArrayList<>(List.of(s));

无论使用上述每个选项,如果您不需要您的列表是可变的,您可以选择不使用 new ArrayList&lt;&gt;() 包装器。

【讨论】:

  • 我很惊讶你是唯一提到Collections.singletonList的人。
  • 我更惊讶于@AndyJ 在我发表评论后发布了Collections.singletonList,得到的票数比你的答案多出 2 倍,而你的答案已经有 3 年了……偶然发现总是很有趣老cmets。
【解决方案4】:

使用 Java 8 流:

Stream.of(object).collect(Collectors.toList())

或者如果你需要一套:

Stream.of(object).collect(Collectors.toSet())

【讨论】:

  • 你也可以使用 Guava 的Sets.newHashSet(objects) 来创建一个新的集合。
  • 我就是喜欢这个
【解决方案5】:

其他答案都使用Arrays.asList(),它返回一个不可修改的列表(如果您尝试添加或删除元素,则会抛出UnsupportedOperationException)。要获得一个可变列表,您可以将返回的列表包装在一个新的 ArrayList 中,正如几个答案指出的那样,但更清洁的解决方案是使用 Guava's Lists.newArrayList() (至少从 Guava 10 开始可用,于 2011 年发布)。

例如:

Lists.newArrayList("Blargle!");

【讨论】:

  • 如果给定元素实现了 Iterable,这将不起作用,例如:Lists.newArrayList(Paths.get("/usr/local/this/is/not/single/element"));你想要的是创建具有单个路径元素的数组,但是,你得到的是一个包含 7 个路径元素的列表。
  • 啊,我明白了。默认情况下是Java will choose the most specific method,在本例中为Lists#newArrayList(Iterable&lt;? extends E&gt; elements)。您可以通过Lists.newArrayList(new Path[] {Paths.get("/usr/local/this/is/not/single/‌​element")}) 显式调用可变参数方法,或者只是构造一个空列表(List&lt;Path&gt; p = Lists.newArrayList())并添加元素(p.add(Paths.get("/usr/local/this/is/not/single/‌​element")))。
【解决方案6】:

很简单:

Arrays.asList("Hi!")

【讨论】:

    【解决方案7】:

    看到 Guava 被提及,我想我也会建议 Eclipse Collections(以前称为 GS Collections)。

    以下示例均返回带有单个项目的 List

    Lists.mutable.of("Just one item");
    Lists.mutable.with("Or use with");
    Lists.immutable.of("Maybe it must be immutable?");
    Lists.immutable.with("And use with if you want");
    

    其他集合也有类似的方法。

    【讨论】:

      【解决方案8】:

      另一种选择是double brace initialization,例如

      new ArrayList<String>() {{ add(s); }};
      

      但是it is inefficient and obscure。因此只适合:

      • 在不介意内存泄漏的代码中,例如大多数单元测试和其他短期程序;
      • 如果没有其他解决方案适用,我认为这意味着您一直向下滚动,希望填充与问题中的 ArrayList 不同类型的容器。

      【讨论】:

      • -1。不仅低劣,而且无效。传递以这种方式实例化的列表将导致创建它的对象不会被垃圾收集。即使您认为您已经将问题隔离并包含在您的脑海中,并告诉自己使用双支架是安全的,因为它看起来非常酷,但充其量是不明智的。除了娱乐之外,谁在这个答案中发现了价值(并且那些在其中发现娱乐价值的人已经知道这一点)可能会继续在他们的项目中写下来。
      • @BenBarkay 我没有看到您的评论在第一个链接的讨论中添加了哪些信息。低效程序不是无效程序。我仍然认为这个答案很有价值,因为我记得为什么不在项目中编写这个结构。
      • 我将避免围绕有效性进行讨论,因为它很可能与语义相关(对问题有效与绝对有效)。这条评论增加的价值在于,它附加了一个更接近于危险的重量警告,就在想法本身的旁边。效率低下、晦涩难懂和不便并不是这种技术的主要功能障碍。
      • 如果您编辑答案以反映如果列表在实例之间共享,使用此技术将导致内存泄漏,我将 +1(导致 +-0)。
      • 这种方法创建了 ArrayList 的子类...想想看。
      猜你喜欢
      • 2014-12-02
      • 1970-01-01
      • 2011-12-25
      • 1970-01-01
      • 2020-02-27
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 2022-01-16
      相关资源
      最近更新 更多