414

Is there a Utility method somewhere that can do this in 1 line? I can't find it anywhere in Collections, or List.

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

I don't want to re-invent the wheel unless I plan on putting fancy rims on it.

Well... the type can be T, and not String. but you get the point. (with all the null checking, safety checks...etc)

Brian
  • 14,610
  • 7
  • 35
  • 43
David T.
  • 22,301
  • 23
  • 71
  • 123
  • 2
    Well, you shouldn't be using that method at all. The places where you are calling the method, just replace the call with the "single line" transformation you are looking for. – Rohit Jain Dec 03 '13 at 18:34
  • @RohitJain could you please specify what you mean? i'm not sure i understand. what do you mean by this "single line transformation"? – David T. Dec 03 '13 at 18:38
  • 4
    I mean, you want to transform everthing inside the method into a single line right? Well, then that method isn't really doing anything that can't be done without it. What you would do is, `return Arrays.asList(s);`. But then what's the point of that extra method? It is just acting as a delegate. Just remove it. And wherever you call `stringToOneElementList(s)`, call `Arrays.asList(s)`, that's it. – Rohit Jain Dec 03 '13 at 18:40
  • 7
    oh okay, i think i understand. well, the only reason i had that method was because i didn't know where that "magic one liner" was. hence, that's why i asked this stackoverflow question in the first place. if i already knew that one line `Arrays.asList(s)`, then why would i ask my question here on stackoverflow? i was surprised to find that this convenience method is in Arrays and not Collections. – David T. Dec 03 '13 at 18:48
  • 2
    `Arrays` is a utility class containing various other methods you might be sing from time to time. The reason this method in `Arrays` class is because, the method is really converting from `array` to a `list`. The method is defined to take var-args. So, whatever arguments you pass to it is internally converted to an array only. And then a list is created out of it. So, that's its designated place - `Arrays`. – Rohit Jain Dec 03 '13 at 18:51
  • 1
    the design in Java was to turn ANY amount of strings into lists, which includes just 1 string (but also means there's only 1 way to do so). in other languages there are more than one way to do something, so i just wanted to know the best way (in this case, only 1 way), for example, ruby, you can say "blah.first" and "blah.last" as opposed to like "blah[0]", which is very convenient and more readable. in Java, that doesn't seem to be the case. sorry, hope that made sense – David T. Dec 03 '13 at 19:00

8 Answers8

569

Fixed size List

The easiest way, that I know of, is to create a fixed-size single element List with Arrays.asList(T...) like

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

Variable size List

If it needs vary in size you can construct an ArrayList and the fixed-sizeList like

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

and (in Java 7+) you can use the diamond operator <> to make it

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

Single Element List

Collections can return a list with a single element with list being immutable:

Collections.singletonList(s)

The benefit here is IDEs code analysis doesn't warn about single element asList(..) calls.

Leo Ufimtsev
  • 6,240
  • 5
  • 40
  • 48
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 3
    that's EXACTLY what i was looking for. thank you! i have no idea why this is in Arrays and not List, or Collections or whatever. – David T. Dec 03 '13 at 18:45
  • 5
    Be careful with this solution. You can't modify the List. If you try to for example add elements to this List, it will throw an UnsupportedOperationException! – Adamsan Aug 28 '14 at 09:33
  • 1
    Also be careful if `s` is an array of non-primitives. You'll end up with an list containing the array elements, rather than a list containing the array. (e.g. `Arrays.asList(new int[]{1,2,3})` is OK, but `Arrays.asList(new String[]{"hello","world"})` is not.) – Michael Anderson Oct 23 '14 at 03:36
  • 61
    Collections.singletonList(elm); is more preferable as it creates immutable list. – Ravish Bhagdev Jun 03 '15 at 10:39
  • 9
    @RavishBhagdev - not always. There are times when you may want to add stuff to the list later. In fact, I used exactly this answer's approach in a path-finding algorithm in graphs. – Chthonic Project Mar 17 '16 at 22:48
  • 1
    Intellij analysis gives the following warning "call to 'asList' with only one argument" – borjab Apr 27 '17 at 10:01
  • 6
    As of JDK9, there will be a method List.of​(E e1) that returns an immutable list (http://download.java.net/java/jdk9/docs/api/java/util/List.html#of-E-) – Nikola Aug 25 '17 at 10:25
  • 1
    A very important drawback of the first approach is that if you try to convert it to ArrayList later, you'll get a ClassCastException because `Arrays.asList returns a List implementation, but it's not a java.util.ArrayList. It happens to have a classname of ArrayList, but that's a nested class within Arrays - a completely different type from java.util.ArrayList` – ACV Oct 30 '18 at 17:31
  • @RavishBhagdev Why would it be preferable to create an immutable list? Most of the time when I create a list with one element I want to keep adding elements to it later – Teleporting Goat Aug 25 '23 at 15:39
392
Collections.singletonList(object)

the list created by this method is immutable.

Andrew
  • 4,696
  • 1
  • 19
  • 17
87

You can use the utility method Arrays.asList and feed that result into a new ArrayList.

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

Other options:

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

and

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

With Java 7+, you may use the "diamond operator", replacing new ArrayList<String>(...) with new ArrayList<>(...).

Java 9

If you're using Java 9+, you can use the List.of method:

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

Regardless of the use of each option above, you may choose not to use the new ArrayList<>() wrapper if you don't need your list to be mutable.

rgettman
  • 176,041
  • 30
  • 275
  • 357
37

With Java 8 Streams:

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

or if you need a set:

Stream.of(object).collect(Collectors.toSet())
Marko Jurisic
  • 844
  • 9
  • 10
21

The other answers all use Arrays.asList(), which returns an unmodifiable list (an UnsupportedOperationException is thrown if you try to add or remove an element). To get a mutable list you can wrap the returned list in a new ArrayList as a couple of answers point out, but a cleaner solution is to use Guava's Lists.newArrayList() (available since at least Guava 10, released in 2011).

For example:

Lists.newArrayList("Blargle!");
user167019
  • 567
  • 1
  • 5
  • 10
  • 1
    This is not working if given element implements Iterable, for example: `Lists.newArrayList(Paths.get("/usr/local/this/is/not/single/element"))`; what you want is create array with single path element, however, what you get is a list contains 7 path element. – bob Dec 06 '16 at 02:52
  • Ah, I see. Yes by default [Java will choose the most specific method](https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.5), which in this case is `Lists#newArrayList(Iterable extends E> elements)`. You can do `Lists.newArrayList(new Path[] {Paths.get("/usr/local/this/is/not/single/‌​element")})` to explicitly call the vararg method, or just construct an empty list (`List p = Lists.newArrayList()`) and add the element (`p.add(Paths.get("/usr/local/this/is/not/single/‌​element"))`). – user167019 Dec 18 '16 at 20:33
15

Very simply:

Arrays.asList("Hi!")
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
5

Seeing as Guava gets a mention, I thought I would also suggest Eclipse Collections (formerly known as GS Collections).

The following examples all return a List with a single item.

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");

There are similar methods for other collections.

vegemite4me
  • 6,621
  • 5
  • 53
  • 79
2

Yet another alternative is double brace initialization, e.g.

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

but it is inefficient and obscure. Therefore only suitable:

  • in code that doesn't mind memory leaks, such as most unit tests and other short-lived programs;
  • and if none of the other solutions apply, which I think implies you've scrolled all the way down here looking to populate a different type of container than the ArrayList in the question.
Community
  • 1
  • 1
Stein
  • 1,558
  • 23
  • 30
  • 2
    -1. Not only is it inferior, it is also invalid. Passing a list that was instantiated this way around will result in that the object that created it will not be garbage collected. Even if you think you've got the problem isolated and contained in your mind, and tell yourself it's safe to use the double-brace because it looks so damn cool, it's ill-advised at best. Whoever finds value in this answer other than recreationally (and those who find recreational value in it already know about this) is potentially going to go ahead and write that in their project. – Ben Barkay Sep 08 '16 at 18:30
  • 2
    @BenBarkay I don't see what information your comment adds to the discussion in the first link. An inefficient program is not an invalid program. I still find value in this answer for remembering why not to write this construct in projects. – Stein Sep 09 '16 at 12:55
  • 1
    I am going to avoid the discussion around validity because it's likely going to be a semantic-related one (valid to the problem vs. valid in absolute terms). The value that this comment adds is that it attaches a warning of weight that is more closely equal to the danger, right next to the idea itself. Inefficiency, obscurity and inconvenience are not the primary dysfunction of this technique. – Ben Barkay Sep 09 '16 at 13:52
  • 1
    If you edit your answer to reflect that use of this technique will result in memory leaks if the list is shared between instances, I will +1 (resulting in +-0). – Ben Barkay Sep 09 '16 at 14:17
  • This approach creates a subclass of ArrayList ... Think about it. – Orri Oct 18 '18 at 07:42