• Post Reply Bookmark Topic Watch Topic
  • New Topic

Convert generic ArrayList to array of specific type  RSS feed

 
Sudhir Srinivasan
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Hi,

My program generates object array from the toArray method on a generic ArrayList and converts to string array. While alternative 1 successfully returns the result,


alternative 2 does not. Here, the code snippet

attempts to clone the original object array 'ob1' by creating a copy, returning its length and casting to string array class. However, throws a

As per the javadoc, the java.lang.ArrayStoreException is raised if an element copied from the original array (in my case ob1) is not of a run-time type that can be stored in an array of class (str1 in the program). Given that the copy should contain the same elements (& their types) and be of same size as the original, why is this exception thrown? Shouldn't this work with generics or does the ArrayList
have to be of specific type for cloning to be effective??

Is there a way to work around this and find a solution.

Any help from the forum experts / members is much appreciated.

Many thanks,
Sudhir
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1000 and 100 are not Strings.
 
Rob Spoor
Sheriff
Posts: 21131
87
Chrome Eclipse IDE Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The proper way to create a List (or any Collection) into an array is to use the other toArray method, and to use generics properly:

If you want to still use a List<Object>, you will need to iterate manually. I see two ways:
1) Create a List<String> to which you first add all String elements, then convert that into a String as shown above
2) Create a String[] as large as the List. Then add all String elements, using a counter variable. Afterwards, if the counter is less than the array size, use Arrays.copyOf to trim the array.
 
Sudhir Srinivasan
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hi Rob,

Thank you for your suggestions and
Rob Spoor wrote:The proper way to create a List (or any Collection) into an array is to use the other toArray method, and to use generics properly:


the sample code.....was of great help!

I tried out both ways
Rob Spoor wrote:
If you want to still use a List<Object>, you will need to iterate manually. I see two ways:
1) Create a List<String> to which you first add all String elements, then convert that into a String as shown above
2) Create a String[] as large as the List. Then add all String elements, using a counter variable. Afterwards, if the counter is less than the array size, use Arrays.copyOf to trim the array.

and was successful.

Suggestion 1:


Your second suggestion answers my question.

To recap:
1. Create object array from the toArray method on a generic ArrayList
2. Create a string array dimensioned to length of object array
3. for...loop to convert each element toString & store in String[] and
4. Arrays.copyOf method should take parameters whose run-time type is understood by the jvm

instead of


In other words - if I've understood your response correctly - String[] is an Object[] and not the other way.

Thanks and regards,
Sudhir

 
Rob Spoor
Sheriff
Posts: 21131
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sudhir Srinivasan wrote:

Almost correct. str1 is already a String[]. You're copying that into a new String[] of exactly the same size. You need to use a different value instead of str1.length. Also, because str1 is already a String[], you can omit the String[].class. The third argument is only necessary in the following scenario:
- You have a reference of type X[] (e.g. X[] == Object[]).
- You know that every element is actually an instance of type Y, with Y extends X (e.g. Y == String).
- You want to get an Y[] out of that.

If you have an X[] and want to get another X[] (e.g. String[] -> String[]), the third argument can be omitted. copyOf will then use the actual class of the first argument (String[]) to create the copy.

In other words - if I've understood your response correctly - String[] is an Object[] and not the other way.

100% correct.
 
Sudhir Srinivasan
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:]Almost correct. str1 is already a String[]. You're copying that into a new String[] of exactly the same size. You need to use a different value instead of str1.length. Also, because str1 is already a String[], you can omit the String[].class.


You are right. str1 being the original array, to be copied into another String[] str2

of the same size as str1.

Use for...loop to convert each element of str1 toString and

finally,


Rob Spoor wrote:The third argument is only necessary in the following scenario:
- You have a reference of type X[] (e.g. X[] == Object[]).
- You know that every element is actually an instance of type Y, with Y extends X (e.g. Y == String).
- You want to get an Y[] out of that.


Got it! I tried the same and it works. Here's how

  • Create an object array ob from the toArray method on a generic ArrayList (shown above)
  • Contents of al2 to be dumped into the newly allocated object array whose size is identical to the size of al2
  • for...loop to convert each element of the object array to String & store in ob and
  • Create String[] and use Arrays.copyOf method, by passing the third argument, to get String[] from ob


  • and the output



    Rob Spoor wrote:If you have an X[] and want to get another X[] (e.g. String[] -> String[]), the third argument can be omitted. copyOf will then use the actual class of the first argument (String[]) to create the copy.


    I'm intrigued by the String[].class and here's my (wild) guess on its working:
    - Define the Array class (being entity class) having a property, say obj, of java type String
    - Generate getters and setters within this class to populate and return the String value
    - String class (being component class to Array) has property, say data, of type char[]
    - String class mapped to STRING table with unique ID (being primary key, foreign key in CHAR table) assigned to each object obj
    - Each char in turn converted to charset and/or bytes understood by jvm and stored in corresponding CHAR table
    - From this internal representation, java retrieves & returns (thru getters) the Class, in this case the String[].class

    Again, its a wild guess and so kindly excuse me if its a load of gibberish. Could you please, therefore, explain its working briefly and suggest any link - that deals with how the Class object of an Array (be it of type int, char, String etc.) is obtained - as reference.

    Many thanks,
    Sudhir




     
    With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!