1265

How might I convert an ArrayList<String> object to a String[] array in Java?

Naman
  • 27,789
  • 26
  • 218
  • 353
Alex
  • 16,375
  • 7
  • 22
  • 19
  • 4
    Have [made this answer](https://stackoverflow.com/a/51545546/1746118) with an updated approach with **JDK-11** introducing a new an equally performant API to `toArray(T[])` and similar in syntax to `Stream.toArray`. – Naman Jul 26 '18 at 18:40

17 Answers17

2069
List<String> list = ..;
String[] array = list.toArray(new String[0]);

For example:

List<String> list = new ArrayList<String>();
//add some stuff
list.add("android");
list.add("apple");
String[] stringArray = list.toArray(new String[0]);

The toArray() method without passing any argument returns Object[]. So you have to pass an array as an argument, which will be filled with the data from the list, and returned. You can pass an empty array as well, but you can also pass an array with the desired size.

Important update: Originally the code above used new String[list.size()]. However, this blogpost reveals that due to JVM optimizations, using new String[0] is better now.

Floern
  • 33,559
  • 24
  • 104
  • 119
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • It shows this warning in logcat: Converting to string: TypedValue{t=0x12/d=0x0 a=3 r=0x7f050009} – Adil Malik Jun 19 '13 at 12:40
  • @ThorbjørnRavnAndersen: the size of the array doesn't make any difference functionally but if you pass it in with the right size, you save the JVM the work of resizing it. – sferencik Oct 26 '15 at 10:57
  • 76
    Turns out that providing a zero-length array, even creating it and throwing it away, is on average faster than allocating an array of the right size. For benchmarks and explanation see here: http://shipilev.net/blog/2016/arrays-wisdom-ancients/ – Stuart Marks Jan 21 '16 at 08:29
  • @StuartMarks It irks me that was only tested on Sun JVMs. There's no guarantee it will be faster on other systems such as ART (Android runtime) or IBM's JVM, which is used a lot on servers. – Powerlord Apr 10 '16 at 22:52
  • @Powerlord I'm sorry that it irks you. Perhaps you could run some tests on these platforms and report the results. I think many people would find them interesting. – Stuart Marks May 12 '16 at 00:43
  • @Nyerguds Can you explain how java's fake generics disallow such function? – Lyuboslav Nov 01 '17 at 17:34
  • 3
    @lyuboslavkanev The problem is that having the generic type in Java isn't enough to actually create objects based on that type; not even an array (which is ridiculous, because that should work for _any_ type). All that can be done with it, as far as I can see, is casting. In fact, to even create objects of the type, you need to have the actual `Class` object, which seems to be completely impossible to derive from the generic type. The reason for this, as I said, is that the whole construction is fake; it's all just stored as Object internally. – Nyerguds Nov 03 '17 at 07:52
  • @Bozho From that article you like to: Bottom line: toArray(new T[0]) seems faster, safer, and contractually cleaner, and therefore should be the default choice now. Future VM optimizations may close this performance gap for toArray(new T[size]), rendering the current "believed to be optimal" usages on par with an actually optimal one. Further improvements in toArray APIs would follow the same logic as toArray(new T[0]) — the collection itself should create the appropriate storage. – jsears Mar 22 '18 at 20:12
257

An alternative in Java 8:

String[] strings = list.stream().toArray(String[]::new);

Java 11+:

String[] strings = list.toArray(String[]::new);
ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
Vitalii Fedorenko
  • 110,878
  • 29
  • 149
  • 111
  • 28
    Or any benefits? – James Watkins Apr 02 '16 at 13:50
  • 1
    I would prefer that syntax, but IntelliJ displays a compiler error with that, complains "T[] is not a functional interface." – Glen Mazza Jul 25 '16 at 16:11
  • 3
    @GlenMazza you can only use `toArray` on a `Stream` object. This compilation error may occur if you reduce the stream using a `Collectors` and then try to apply `toArray`. – Udara Bentota Nov 16 '16 at 07:29
  • I don't get it. `String[]::new` is equivalent to `() -> new String[]`. But the given interface method expects an integer. Shouldn't it be `(list.size()) -> new String[]`, so `String[list.size()]::new` ? – John Strood Dec 11 '20 at 14:31
  • 2
    @JohnStrood `String[]::new` is equivalent to `i -> new String[i]`. See https://stackoverflow.com/questions/29447561/how-do-java-8-array-constructor-references-work – Unmitigated Feb 11 '21 at 06:37
  • @iota Thank you! That makes more sense now. – John Strood Feb 11 '21 at 12:59
  • @JohnStrood No problem. – Unmitigated Feb 11 '21 at 14:06
  • Java 20: String[] strings = list.toArray(); – Lluis Martinez Apr 13 '22 at 08:31
  • @LluisMartinez I'm confused by your comment. First of all, Java 20 wasn't released until March of 2023, yet your comment is from almost a year before that. Also, `Collection#toArray()`, which `List` inherits, returns an `Object[]`, not a `String[]`. I'm not seeing anything in Java 20 that changes that. So, `String[] strings = list.toArray();` should fail to compile. – Slaw Apr 28 '23 at 01:20
54

Starting from Java-11, one can use the API Collection.toArray(IntFunction<T[]> generator) to achieve the same as:

List<String> list = List.of("x","y","z");
String[] arrayBeforeJDK11 = list.toArray(new String[0]);
String[] arrayAfterJDK11 = list.toArray(String[]::new); // similar to Stream.toArray
Naman
  • 27,789
  • 26
  • 218
  • 353
49

You can use the toArray() method for List:

ArrayList<String> list = new ArrayList<String>();

list.add("apple");
list.add("banana");

String[] array = list.toArray(new String[list.size()]);

Or you can manually add the elements to an array:

ArrayList<String> list = new ArrayList<String>();

list.add("apple");
list.add("banana");

String[] array = new String[list.size()];

for (int i = 0; i < list.size(); i++) {
    array[i] = list.get(i);
}

Hope this helps!

codecubed
  • 780
  • 7
  • 8
33
ArrayList<String> arrayList = new ArrayList<String>();
Object[] objectList = arrayList.toArray();
String[] stringArray =  Arrays.copyOf(objectList,objectList.length,String[].class);

Using copyOf, ArrayList to arrays might be done also.

SkyWalker
  • 28,384
  • 14
  • 74
  • 132
Rajesh Vemula
  • 347
  • 3
  • 2
11

In Java 8:

String[] strings = list.parallelStream().toArray(String[]::new);
Mike Shauneu
  • 3,201
  • 19
  • 21
  • 13
    This is really already contained in [this answer](http://stackoverflow.com/a/30302969/3745896). Perhaps add it as an edit to that answer instead of as an entirely new one. – River Feb 05 '16 at 16:17
  • 16
    Why `parallelStream()` instead of simply `stream()`? – Yoory N. Feb 14 '18 at 12:44
8

In Java 8, it can be done using

String[] arrayFromList = fromlist.stream().toArray(String[]::new);
KayV
  • 12,987
  • 11
  • 98
  • 148
6

Generics solution to covert any List<Type> to String []:

public static  <T> String[] listToArray(List<T> list) {
    String [] array = new String[list.size()];
    for (int i = 0; i < array.length; i++)
        array[i] = list.get(i).toString();
    return array;
}

Note You must override toString() method.

class Car {
  private String name;
  public Car(String name) {
    this.name = name;
  }
  public String toString() {
    return name;
  }
}
final List<Car> carList = new ArrayList<Car>();
carList.add(new Car("BMW"))
carList.add(new Car("Mercedes"))
carList.add(new Car("Skoda"))
final String[] carArray = listToArray(carList);
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Khaled Lela
  • 7,831
  • 6
  • 45
  • 73
6

You can use Iterator<String> to iterate the elements of the ArrayList<String>:

ArrayList<String> list = new ArrayList<>();
String[] array = new String[list.size()];
int i = 0;
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); i++) {
    array[i] = iterator.next();
}

Now you can retrive elements from String[] using any Loop.

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Vatsal Chavda
  • 129
  • 2
  • 8
  • I downvoted because: 1. no use of generics which force you into 2. using `.toString()` where no explicit cast would be needed, 3. you don't even increment `i`, and 4. the `while` would be better off replaced by a `for`. Suggested code: `ArrayList stringList = ... ; String[] stringArray = new String[stringList.size()]; int i = 0; for(Iterator it = stringList.iterator(); it.hasNext(); i++) { stringArray[i] = it.next(); }` – Olivier Grégoire Aug 28 '17 at 09:05
  • Okay, I got it now. Thanks. – Vatsal Chavda Aug 28 '17 at 13:50
  • Well, ideally, you should edit your code to include those comments (that is... if you think they're good for your answer!). I won't consider removing my downvote while the code remains unchanged. – Olivier Grégoire Aug 28 '17 at 13:58
  • I am new here, so I don't know yet how things work here. Although, appreciate your help mate. – Vatsal Chavda Aug 28 '17 at 14:18
  • This is much better! I've edited just a bit, but you've just experienced how it works: provide answer, improve them, get the laurels ;) – Olivier Grégoire Aug 28 '17 at 14:22
6

If your application is already using Apache Commons lib, you can slightly modify the accepted answer to not create a new empty array each time:

List<String> list = ..;
String[] array = list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);

// or if using static import
String[] array = list.toArray(EMPTY_STRING_ARRAY);

There are a few more preallocated empty arrays of different types in ArrayUtils.

Also we can trick JVM to create en empty array for us this way:

String[] array = list.toArray(ArrayUtils.toArray());

// or if using static import
String[] array = list.toArray(toArray());

But there's really no advantage this way, just a matter of taste, IMO.

Yoory N.
  • 4,881
  • 4
  • 23
  • 28
6
    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    String [] strArry= list.stream().toArray(size -> new String[size]);

Per comments, I have added a paragraph to explain how the conversion works. First, List is converted to a String stream. Then it uses Stream.toArray to convert the elements in the stream to an Array. In the last statement above "size -> new String[size]" is actually an IntFunction function that allocates a String array with the size of the String stream. The statement is identical to

IntFunction<String []> allocateFunc = size -> { 
return new String[size];
};   
String [] strArry= list.stream().toArray(allocateFunc);
nick w.
  • 139
  • 3
  • 4
  • 4
    What value does this answer add? It appears to just repeat other answers without explaining why it answers the question. – Richard Feb 21 '19 at 07:56
5
List <String> list = ...
String[] array = new String[list.size()];
int i=0;
for(String s: list){
  array[i++] = s;
}
HZhang
  • 223
  • 1
  • 3
5

in case some extra manipulation of the data is desired, for which the user wants a function, this approach is not perfect (as it requires passing the class of the element as second parameter), but works:

import java.util.ArrayList; import java.lang.reflect.Array;

public class Test {
  public static void main(String[] args) {
    ArrayList<Integer> al = new ArrayList<>();
    al.add(1);
    al.add(2);
    Integer[] arr = convert(al, Integer.class);
    for (int i=0; i<arr.length; i++)
      System.out.println(arr[i]);
  }

  public static <T> T[] convert(ArrayList<T> al, Class clazz) {
    return (T[]) al.toArray((T[])Array.newInstance(clazz, al.size()));
  }
}
Roberto Attias
  • 1,883
  • 1
  • 11
  • 21
5

In Java 11, we can use the Collection.toArray(generator) method. The following code will create a new array of strings:

List<String> list = List.of("one", "two", "three");
String[] array = list.toArray(String[]::new)

from java.base's java.util.Collection.toArray().

Sled
  • 18,541
  • 27
  • 119
  • 168
Rafal Borowiec
  • 5,124
  • 1
  • 24
  • 20
2

You can convert List to String array by using this method:

 Object[] stringlist=list.toArray();

The complete example:

ArrayList<String> list=new ArrayList<>();
    list.add("Abc");
    list.add("xyz");

    Object[] stringlist=list.toArray();

    for(int i = 0; i < stringlist.length ; i++)
    {
          Log.wtf("list data:",(String)stringlist[i]);
    }
Ernestas Gruodis
  • 8,567
  • 14
  • 55
  • 117
1
private String[] prepareDeliveryArray(List<DeliveryServiceModel> deliveryServices) {
    String[] delivery = new String[deliveryServices.size()];
    for (int i = 0; i < deliveryServices.size(); i++) {
        delivery[i] = deliveryServices.get(i).getName();
    }
    return delivery;
}
Denis Fedak
  • 436
  • 4
  • 8
0

An alternate one-liner method for primitive types, such as double, int, etc.:

List<Double> coordList = List.of(3.141, 2.71);
double[] doubleArray = coordList.mapToDouble(Double::doubleValue).toArray();
List<Integer> coordList = List.of(11, 99);
int[] intArray = coordList.mapToInt(Integer::intValue).toArray();

and so on...