Java Forum / General / October 2005
Vector to array?
wang - 19 Oct 2005 11:08 GMT Hi all, I've tried to use Vector.toArray() to copy the content of a vector to an array without success. The vector contains only object of the class MyClass. I've made the following attempts:
MyClass[] arr = new MyClass[myVector.size()]; arr = (MyClass)myVector.toArray();
or: arr = (MyClass[])myVector.toArray();
or: arr = myVector.toArray(arr);
How should the method toArray() be used? Thanks in advance!
k.w.wang
Mat - 19 Oct 2005 13:03 GMT > Hi all, > I've tried to use Vector.toArray() to copy the content of a vector [quoted text clipped - 13 lines] > > k.w.wang I don't know exactly why, but I use :
MyClass[] arr; arr = (MyClass[])myVector.toArray(new MyClass[myVector.size()]);
Mat
Massimo Dell'Andrea - 19 Oct 2005 15:06 GMT > I don't know exactly why, but I use : > > MyClass[] arr; > arr = (MyClass[])myVector.toArray(new MyClass[myVector.size()]); > > Mat or MyClass[] arr = (MyClass[])myVector.toArray(new MyClass[0]);
or MyClass[] arr = (MyClass[])myVector.toArray(new MyClass[]{});
or MyClass[] arr = new MyClass[myVector.size]); myVector.toArray(arr);
Babu Kalakrishnan - 19 Oct 2005 18:38 GMT >> I don't know exactly why, but I use : >> [quoted text clipped - 12 lines] > MyClass[] arr = new MyClass[myVector.size]); > myVector.toArray(arr); Solutions (1) and (2) are really not worth using because they (unnecessarily) create an extra Array object. The third solution (assuming that you correct it by replacing "size" with "size()") is indeed the best solution - it's actually the same as what Mat proposed, since the API guarantees that the argument passed will be returned with the values filled in if the Collection will fit into it.
BK
Monique Y. Mudama - 19 Oct 2005 18:31 GMT > Hi all, > I've tried to use Vector.toArray() to copy the content of a vector [quoted text clipped - 13 lines] > > k.w.wang This doesn't directly answer your question, but that new is unnecessary. You're allocating memory, then instantly dropping your only reference to it.
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Roedy Green - 19 Oct 2005 23:49 GMT >This doesn't directly answer your question, but that new is >unnecessary. You're allocating memory, then instantly dropping your >only reference to it. You could show us the abbreviated syntax you think will work? I don't follow you.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Monique Y. Mudama - 20 Oct 2005 00:18 GMT >>This doesn't directly answer your question, but that new is >>unnecessary. You're allocating memory, then instantly dropping your >>only reference to it. > > You could show us the abbreviated syntax you think will work? I > don't follow you. Well, you could have made my job easier by including the code to which I was referring ...
(not posted by Roedy)
> MyClass[] arr = new MyClass[myVector.size()]; > arr = (MyClass)myVector.toArray(); Without paying any attention to whether or not the desired result is accomplished, it looks to me like the reference arr is being assigned to a new array, and then immediately reassigned to a different array. So the new array is simply being allocated, then immediately lost to eventually be snagged by the GC.
Am I missing something?
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Roedy Green - 20 Oct 2005 01:37 GMT >Well, you could have made my job easier by including the code to which >I was referring ... That's the problem. I could not tell.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Roedy Green - 20 Oct 2005 01:44 GMT >> MyClass[] arr = new MyClass[myVector.size()]; >> arr = (MyClass)myVector.toArray(); [quoted text clipped - 3 lines] >to a new array, and then immediately reassigned to a different array. >So the new array is simply being I see what you mean now. It is not just he keyword "new" you would delete, but that whole line and just collapse it to:
MyClass[] arr = (MyClass)myVector.toArray();
This code won't work. The cast will fail since toArray without a model to follow, will produce an Object[].
You would have to write that as
MyClass[] arr = (MyClass) myVector.toArray( new MyClass[ myVector.size() ] );
With generics you could drop the cast, and clever folk might prune it even further. What I think the OP meant to say was:
MyClass[] arr = new MyClass[ myVector.size() ]; arr = (MyClass) myVector.toArray( arr );
or perhaps: MyClass[] arr = new MyClass[ myVector.size() ]; myVector.toArray( arr );
The first code will work even if the size is off a tad. The second will not.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Monique Y. Mudama - 20 Oct 2005 06:51 GMT >>> MyClass[] arr = new MyClass[myVector.size()]; >>> arr = (MyClass)myVector.toArray(); [quoted text clipped - 11 lines] > This code won't work. The cast will fail since toArray without a model > to follow, will produce an Object[]. Oh.
I thought this was a newbie "defensive new" thing. Instead, you're saying that the quoted code works, and more importantly if you remove the new, it doesn't?
Now I'm the one who's feeling like a newbie, because I find that to be really bizarre. Granted, I've never played with toArray(), but ...
Well, I guess now I have to.
> You would have to write that as > [quoted text clipped - 15 lines] > The first code will work even if the size is off a tad. The second > will not.
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Roedy Green - 20 Oct 2005 08:59 GMT >> MyClass[] arr = (MyClass)myVector.toArray(); >> [quoted text clipped - 6 lines] >saying that the quoted code works, and more importantly if you remove >the new, it doesn't? That code on the top line will fail. The problem is toArray not know the type of the thing on the right, so all it can do is produce an Object[] filled with MyClasses, which is a totally different animal that a MyClass[] filled with MyClasses. It can't be cast to MyClass[].
If you give it a MyClass[] the right size to fill, or even an exemplar empty MyClass[] array, then it knows the desired type of array.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Monique Y. Mudama - 21 Oct 2005 17:01 GMT >>> MyClass[] arr = (MyClass)myVector.toArray(); [snip]
> That code on the top line will fail. The problem is toArray not > know the type of the thing on the right, so all it can do is produce [quoted text clipped - 5 lines] > exemplar empty MyClass[] array, then it knows the desired type of > array. That strikes me as relying on a side effect to have the code function. Isn't that bad design?
 Signature monique
Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html
Roedy Green - 22 Oct 2005 01:13 GMT >> If you give it a MyClass[] the right size to fill, or even an >> exemplar empty MyClass[] array, then it knows the desired type of >> array. > >That strikes me as relying on a side effect to have the code function. >Isn't that bad design? The term side effect usually refers to a method changing something not one of the inputs or outputs. What do you mean by that term?
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Hemal Pandya - 20 Oct 2005 08:21 GMT > I see what you mean now. It is not just he keyword "new" you would > delete, but that whole line and just collapse it to: > > MyClass[] arr = (MyClass)myVector.toArray(); > > This code won't work. It won't even compile, it converts an Object to an Array. Or am I missing something?
Roedy Green - 20 Oct 2005 09:11 GMT >> MyClass[] arr = (MyClass)myVector.toArray(); >> >> This code won't work. > >It won't even compile, it converts an Object to an Array. Or am I >missing something? The following analogous program will compile, but it fails with a CastCastException on run.
import java.util.ArrayList; public class CastExper { /** * test harness * * @param args not used */ public static void main ( String[] args ) { ArrayList a = new ArrayList(10); a.add( "elephant" ); a.add( "beanbag" ); String[] things = (String[])a.toArray(); for ( String thing: things ) { System.out.println( thing ); } } }
This is how you would do it with generics
import java.util.ArrayList; public class CastExper { /** * test harness * * @param args not used */ public static void main ( String[] args ) { ArrayList<String> a = new ArrayList<String>(10); a.add( "elephant" ); a.add( "beanbag" ); String[] things = a.toArray( new String[ a.size() ] ); for ( String thing: things ) { System.out.println( thing ); } } }
The following code will not compile, even though you would think toArray could, if it were written differently, might take advantage of its knowledge that a was an ArrayList<String>. toArray() is defined without any generics. Because of type erasure, that knowledge is useless in determining the actual return type. The information is not around at run time to instantiate the precisely correct type of array.
String[] things = a.toArray();
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Hemal Pandya - 21 Oct 2005 04:15 GMT > >> MyClass[] arr = (MyClass)myVector.toArray(); > >> [quoted text clipped - 4 lines] > > The following analogous program will compile, Yes it will, because it does not have the erroneous conversion from Object[] to Object.
> This is how you would do it with generics You had earlier mentioned that the case is not required with generics, but it wasn't clear to me how. Thank you for this explanation.
Roedy Green - 21 Oct 2005 08:31 GMT >Yes it will, because it does not have the erroneous conversion from >Object[] to Object. What code are you referring to? It is quite legal to cast an Object[] to Object.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Thomas Weidenfeller - 20 Oct 2005 08:47 GMT >>MyClass[] arr = new MyClass[myVector.size()]; >>arr = (MyClass)myVector.toArray(); > > Without paying any attention to whether or not the desired result is > accomplished, it looks to me like the reference arr is being assigned > to a new array, and then immediately reassigned to a different array. Not necessarily.
> So the new array is simply being allocated, then immediately lost to > eventually be snagged by the GC. > > Am I missing something? You are missing how Vector.toArray() works. If the Vector fits in the supplied array, it will *return a reference to the supplied array*! toArray() will only allocate a new array if the Vector doesn't fit.
There are basically two tricks to use toArray successfully:
1) Supply an array of the desired type. Otherwise, if you use the version of the toArray() method with doesn't require an argument, you get an Object[].
2) Supply a large enough array. Otherwise toArray() will allocate an new array (but at least of the supplied type).
Ok, and of course, if you run in a multithreaded environment, you need to take care of locking/protecting the Vector when you do this.
/Thomas
 Signature The comp.lang.java.gui FAQ: ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/
Thomas Hawtin - 20 Oct 2005 09:05 GMT > You are missing how Vector.toArray() works. If the Vector fits in the > supplied array, it will *return a reference to the supplied array*! > toArray() will only allocate a new array if the Vector doesn't fit.
> Ok, and of course, if you run in a multithreaded environment, you need > to take care of locking/protecting the Vector when you do this. Not entirely. The worst that could happen, would be some nulls on the end of the array.
The toArray is an atomic operation, so no need to worry about that. If the Vector grows between finding it's size and toArray, then the array gets reallocated. If it shrinks, you just get a few nulls at the end. (The reference immediately after the end of the valid values is always set to null, even if it wasn't before.)
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Roedy Green - 21 Oct 2005 08:33 GMT >>>MyClass[] arr = new MyClass[myVector.size()]; >>>arr = (MyClass)myVector.toArray(); [quoted text clipped - 13 lines] >supplied array, it will *return a reference to the supplied array*! >toArray() will only allocate a new array if the Vector doesn't fit. I think you may have overlooked the fact that in that particular example he failed to pass the array to toArray(). So allocation was pointless.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
wang - 21 Oct 2005 10:52 GMT With your help I've solved the problem. Thank you all!
k.w.wang
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|