4

I was just wondering what is the difference between following two approach of converting List to Array.

List<String> test = new ArrayList<String>();
test.add("AB");
test.add("BC");
test.add("CD");
test.add("DE");
test.add("EF");

String[] testarray = test.toArray(new String[0]); // passing 0 as Array size

And below one :

List<String> test = new ArrayList<String>();
test.add("AB");
test.add("BC");
test.add("CD");
test.add("DE");
test.add("EF");

String[] testarray = test.toArray(new String[test.size()]); // passing list's size

I got the same output for testarray on console.

Vimal Bera
  • 10,346
  • 4
  • 25
  • 47
  • Which java version are you using? – Jordi Castilla May 27 '15 at 11:22
  • This is what the docs for JDK7 have to say about this: **toArray(T[] a) Returns an array containing all of the elements in this list in proper sequence (from first to last element); the runtime type of the returned array is that of the specified array.** – Robin-Hoodie May 27 '15 at 11:22
  • Performance wise the second method will be slower you are pre-allocating memory – The6thSense May 27 '15 at 11:23
  • Link to documentation: https://docs.oracle.com/javase/7/docs/api/java/util/List.html#toArray() – User404 May 27 '15 at 11:23
  • @VigneshKalai will it not be re-used? – Niklas R May 27 '15 at 11:23
  • @NiklasR Also from documentation: ' If the list fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this list.' – User404 May 27 '15 at 11:24
  • @NiklasR Java is called robust because it reuses – The6thSense May 27 '15 at 11:25
  • Duplicate of http://stackoverflow.com/questions/14280631/pass-zero-sized-array-save-allocation – scottb May 27 '15 at 11:26
  • 4
    @VigneshKalai the first one will actually be marginally slower, since you create a useless empty array and force toList() to create a second one of the right size. – JB Nizet May 27 '15 at 11:31
  • @JBNizet now it's make more sense in terms of performance..!! – Vimal Bera May 27 '15 at 11:33
  • @JBNizet - If the size of the array being passed is sufficiently large (to hold elements of list), then the first one will be *marginally faster* :P – TheLostMind May 27 '15 at 11:35
  • @JBNizet That's what I thought too, until I tested it: http://stackoverflow.com/a/29444594/829571 – assylias May 27 '15 at 11:35
  • @assylias I think we can all agree that if the goal is to have a new array and not to overwrite an existing array, both are equivalent and the difference in performance is so negligible that it doesn't really matter. – JB Nizet May 27 '15 at 11:39
  • @assylias - The code actually suggests otherwise. If the size of array is `0`, then `Arrays.copyOf` is called. Whereas if the size of array is large enough to hold all elements of list, then `System.arraycopy` is called. Internally, `Arrays.copyOf` also calls `System.arraycopy` after executing some *rather complex* instruction(s). – TheLostMind May 27 '15 at 11:44
  • 1
    @TheLostMind Arrays#copyOf is intrinsic in hotspot so that code is not really run (so is System.arraycopy) - see line 748 of [this file](http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/classfile/vmSymbols.hpp#l748). – assylias May 27 '15 at 11:56
  • @assylias - Oh. So the code is optimized by the hotspot.. Thanks :) – TheLostMind May 27 '15 at 12:07
  • @JBNizet yes you are right – The6thSense May 27 '15 at 12:09

1 Answers1

11
public <T> T[] toArray(T[] a)

a - This is the array into which the elements of the list are to be stored, if it is big enough; otherwise, a new array of the same runtime type is allocated for this purpose. So in first case a new array is being created while in second case, it is using the same array.

Sample Code :

Case -1 : array being passed can hold elements of list

public static void main(String[] args) {
        List<String> test = new ArrayList<String>();
        test.add("AB");
        test.add("BC");
        test.add("CD");
        test.add("DE");
        test.add("EF");
        String[] s= new String[10];
        String[] testarray = test.toArray(s); 
        System.out.println(s==testarray);
    }

O/P :

true

Case-2 : Array being passed cannot hold elements of list

public static void main(String[] args) {
        List<String> test = new ArrayList<String>();
        test.add("AB");
        test.add("BC");
        test.add("CD");
        test.add("DE");
        test.add("EF");
        String[] s= new String[0];
        String[] testarray = test.toArray(s); 
        System.out.println(s==testarray);

    }

O/P :

false
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
Ouney
  • 1,164
  • 1
  • 10
  • 22