File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Cloning Vectors Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Cloning Vectors" Watch "Cloning Vectors" New topic
Author

Cloning Vectors

Steve Cannon
Greenhorn

Joined: Jan 17, 2003
Posts: 8
I have a vector that I am passing to a method. I need to do come computations and then do one of three things:
1) Hand the Vector back, unchanged;
2) Remove the first element from the Vector and hand the shortened one back;
3) Remove a range of elements and hand that shortened Vector back.

When I looked in the Vector API, there was a protected method called removeRange which looked cool. So I added




to my code thinking I could then use removeRange without a problem. Rather than loop through the Vector and copy each element into a new MyVector, I thought I could just clone the Vector, but I'm getting "java.lang.ClassCastException: java.util.Vector" at the line where I create the clone, Vector rtn = currList.clone();

My code looks like this:




I'm self taught in Java. My questions are:
1) Why am I getting the cast exception?
2) Is there a smarter way to user removeRange?
3) Is there a smarter way to do what I want period?

Thanks in advance for any help.

[ September 30, 2004: Message edited by: Steve Cannon ]
[ September 30, 2004: Message edited by: Steve Cannon ]
Peter van der Linden
author
Ranch Hand

Joined: Sep 28, 2004
Posts: 46
Hi Steve,

You're doing the right kind of thing, so obviously when you say you are self-taught,
you had a great teacher!

Nothing jumps out at me to suggest why you are having a problem at run time with
a class cast exception. Maybe someone else with sharper eyes will spot something.

However, I do see a problem with that code which should be caught at compile time!
Namely, this. If you look at the definition of Vector.clone() it returns an Object, not
a Vector.

Therefore to make an assignment like this:

should be flagged as an error by the compiler, saying something like:


You would fix it with a cast like this:


I don't know why you didn't see that error, but suspect this is part of the problem.
Cheers,

Peter


Author of <a href="http://www.amazon.com/exec/obidos/ASIN/0131482114/ref=jranch-20" target="_blank" rel="nofollow">Just Java(TM) 2 (6th Edition)</a>
Peter van der Linden
author
Ranch Hand

Joined: Sep 28, 2004
Posts: 46
Also....

One other thing to watch with removeRange()

It is one of those devastating routines where the arguments are not (lower, upper),
but (lower, upper_plus_one). In other words, you have to give it an upper argument of
ONE BEYOND WHERE YOU WANT TO DROP FROM THE LIST!

Say you have a Vector of strings:
"egg salad", "labrador", "poodle", "dalmatian", "spaniel", "soup", "cheese"
and you want to take out the range of dogs. You must give the arguments
removeRange(1, 5) NOT removeRange(1, 4); as you might assume.

I don't see enough of your code to know if you got this right or wrong, but it
is a convention that often introduces bugs, and the online API doesn't spell it out
as well as it should.

Cheers!

Peter
Steve Cannon
Greenhorn

Joined: Jan 17, 2003
Posts: 8
Thanks, actually I was casting it.

I was debugging and didn't post the actual code. The code that was throwing the error was


Sorry for the confusion.
Steve Cannon
Greenhorn

Joined: Jan 17, 2003
Posts: 8
Thanks for the heads up on removeRange(). I didn't know that one.
[ September 30, 2004: Message edited by: Steve Cannon ]
Sonny Gill
Ranch Hand

Joined: Feb 02, 2002
Posts: 1211

Steve,

This is just a guess from having a quick look at this post of yours -


MyVector rtn = (MyVector) currList.clone();


If you havent overridden clone() in your Vector subclass, that method would be returning an object of class Vector, which you are trying to cast into MyVector, and hence the ClassCastException.

Is there any good reason why you dont want to call the remove(int index) method in a loop to remove the required range of elements. Something like -



I am not sure of the performance effect of that though.
That I suppose will depend on whether the elements removed are in the middle, beginning or end, and how often it is done. You may want to look at another data structure such as a LinkedList in that case.

HTH
Sonny


The future is here. It's just not evenly distributed yet. - William Gibson
Consultant @ Xebia. Sonny Gill Tweets
Steve Cannon
Greenhorn

Joined: Jan 17, 2003
Posts: 8
Sonny,
Thanks for the explanation. That makes sense. I tried to write an overloaded method in my subclass, but couldn't get it to work. After rereading your post, I decided maybe I was being too clever and should just use a normal vector as you said. I ended up changing the code like so:


If it's not too much trouble, how would I write an overloaded method in my subclass? Could you provide an example? Also, I had thought a clone was a copy, but from what I've read, I'm now starting to think it's a copy but one that shares the same memory address as the obj being cloned. Is that correct?
[ September 30, 2004: Message edited by: Steve Cannon ]
Peter van der Linden
author
Ranch Hand

Joined: Sep 28, 2004
Posts: 46
Also, I had thought a clone was a copy, but from what I've read, I'm now starting to think it's a copy but one that shares the same memory address as the obj being cloned. Is that correct?


Eeeek! No! A clone is a copy of some object. That means that all the data fields in the object
get copied to a fresh area of memory, and the address of that fresh area is returned from
the clone() method.

Now... some of the data fields that were copied might themselves be a reference to some other
object. What do we do with them? Do we follow the reference to that other object, and also
make a copy of *it*? And what if that second object that we just copied also contains references
to a third object?

Making copies of an object and copies of everything it refers to, and so on is termed a "deep copy".
Making copies only of the first object data fields, and sharing the objects that it refers to
is termed a "shallow copy".
Shallow copies are done by default in Object.clone().
But you have the ability to override Object's version of clone() and provide a deep clone if you
wish, or a shallow clone() or indeed anything in between.

Hope this clears it up.
Cheers,

Peter
Sonny Gill
Ranch Hand

Joined: Feb 02, 2002
Posts: 1211

Hi Steve,

Peter has already answered your question about using clone. In addition to that, here is another link (to Bruce Eckel's Thinking in Java) which discusses using clone.

http://www.codeguru.com/java/tij/tij0127.shtml

You asked about overloading a method, but I suspect what you are interested in is how to override a method. These two are very different concepts, and both relate to polymorphism. Again, instead of giving you an amateurish, half baked explanation, it's probabely better that I point you to some relevant material on the net
TIJ - Polymorphism
Sun's Java Tutorial - Overriding methods
Hope that helps.

cheers mate,
Sonny
Steve Cannon
Greenhorn

Joined: Jan 17, 2003
Posts: 8
Peter,
Thanks. That clears it up. I'll do some more reading on the subject.

Thanks again.
Steve Cannon
Greenhorn

Joined: Jan 17, 2003
Posts: 8
Sonny,

Yes, I misspoke and mean overriding the method. I will take a look at the links you sent.

Thanks for the assistance and references.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Cloning Vectors