0

I'm trying to convert List type data collection into array.

    public void method1(List s1){
    List s=s1;
    String []array = new String[s.size()];
    array=(String[])s.toArray(); 
    for(int i=0;i<array.length;i++){
        System.out.println(array[i]);
    }
    }

Then following class cast exception occurs. Error line was "array=(String[])s.toArray();" line.

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

What is reason for that?

Maduri
  • 239
  • 1
  • 5
  • 18

2 Answers2

2

List.toArray() is a method in the interface List, and the documentation does not specify what kind of array is returned by the method. However, unlike other answers suggested, the List.toArray() method cannot return an array of the generic type of the list, because the generic type of a list is not known at runtime.

Because of that, all the implementations of List that are built-in to the standard API return an Object[], and not a String[].

However, you are allowed to pass your own pre-allocated array into the method List.toArray(Object[]). If you do that, you are guaranteed to get a return value that has the same element type as the array that you passed in. If the array that you passed in has the same size as the list itself, then that array will be used (otherwise, a new array of the proper size is allocated internally)

This will fix it:

public void method1(List s) {
    String[] array = s.toArray(new String[s.size()]);  // <-- pass the array as an argument
    for (int i = 0; i < array.length; i++) {
        System.out.println(array[i]);
    }
}
Erwin Bolwidt
  • 28,093
  • 15
  • 46
  • 70
  • Except you don't need to cast. The toArray(T[]) method IS templated. – The Real Diel Nov 27 '14 at 14:05
  • 1
    It is not necessary to create the array with the correct size. `String[] array = s.toArray(new String[0]);` works as well. Or to avoid the `empty array` warning use `String[] array = s.toArray(new String[1]);` – Tom Nov 27 '14 at 14:10
  • 1
    @Erwin Bolwidt Thanx lot. That worked for me :).Have a nice day . – Maduri Nov 27 '14 at 14:11
  • 2
    @Tom It is a bad idea to create an array of the wrong size, as this creates an instance of an array that you *know* is not going to be needed. Whether or not HotSpot catches that or not, it's wasteful. The problem with new String[1] is that you'll still get an array of size one if the list had size zero. – Erwin Bolwidt Nov 27 '14 at 14:11
  • 1
    Tom: The toArray(T[]) method will use the array passed in if all of the elements can fit into it. Otherwise it will allocate a new array. So it is beneficial to initialize an array of the size of the list. It makes sense to. – The Real Diel Nov 27 '14 at 14:13
1

You didn't specify the generic type for list, and you declared array as array of Strings. This should work:

public void method1(List<String> s1){
    List<String> s=s1;
    String []array = new String[s.size()];
    array = (String[])s.toArray(array); 
    for(int i=0;i<array.length;i++){
        System.out.println(array[i]);
    }
}

EDIT
Instead of List#toArray() which returns Object[], you should use List#toArray(T[] a) which returns the type passed in as a parameter.

Predrag Maric
  • 21,996
  • 4
  • 45
  • 64
  • 1
    Note for the the OP: Assigning s1 to s just gives a reference to the same list. As far as I know it isn't actually doing anything for you. You can probably omit that line. Note for this answer: Do array = s.ToArray(array); I believe that will work. – The Real Diel Nov 27 '14 at 13:59
  • @TheRealDiel You're right, it works. As for `s = s1`, I've kept that part since often the code posted by OP is simplified version of some bigger and more complicated code, so keeping the original code structure in the answer is easier to apply to the real code for the OP. – Predrag Maric Nov 27 '14 at 14:04
  • I understand. It was more of a comment to OP rather than to you. I noted as such. But I suppose I shouldn't be answering things I'm not asked. :) – The Real Diel Nov 27 '14 at 14:06
  • @TheRealDiel I know it was for the OP, I just kind of explained my view on the point (answered thing I wasn't asked) :) – Predrag Maric Nov 27 '14 at 14:13