Tutorial :Efficiently typecast elements of a vector in Java



Question:

Is there a more efficient way (preferably O(1) rather than O(n) but at least faster to type) to typecast the elements of a vector than this?

public Vector<String> typecastVector(Vector<Object> objects){      Vector<String> strings = new Vector<String>();      for(Object o : objects)          strings.add((String) o);      return strings;  }  

Note

To anyone who is running into an apparent need to typecast a Vector or other Generic class: as the accepted answerer points out, this is probably a code smell and you probably need to refactor the code in your class hierarchy.

Specifically, if you haven't already, you should consider making the classes that use said Vector or other Generic class use Generics themselves. When I did this in my own code, I completely eliminated the need for the function in my code that was analogous to the above function.

If you've never implemented Generics in your own code, check the "Generics" link above. You may be surprised (as I was) to find that they can be used to implement precisely the functionality you thought you needed from a Vector typecast.


Solution:1

If the only thing you want to do is to cast from Vector<Object> to Vector<String>, that you can do. You'll have to be sure every object in your vector is a String though!

Obviously, this won't work:

    Vector<Object> objectVector = new Vector<Object>();      Vector<String> stringVector = (Vector<String>)objectVector;  

But you can do this:

    Vector<Object> objectVector = new Vector<Object>();      Vector typelessVector = objectVector;      Vector<String> stringVector = (Vector<String>)typelessVector;  

You'll get some warnings, but the code should work fine.

As was mentioned before, this does feel like a code smell.


Solution:2

If you're definitely trying to create a new independent collection which contains a copy of N references, it's hard to see how that could possibly be O(1) without something like copy-on-write support.

Have you found this to actually be a performance bottleneck in your code? And is there any reason why you're using Vector instead of ArrayList?


Solution:3

If you think a bit about it, you will unsderstand that if you have to convert every element of the array that you will always end up with O(n).

Since the compiler cannot know in advance if all objects in the object vector are all strings, you cannot cast the vector directly, but only element by element.


Solution:4

That is indeed the best way to do it.

In order to cast n elements to a String, you will need to 'process' all n elements. That implies that the lower bound on the running time is going to have to be O(n).

As far as typing goes, you have already done all of the work. Just put that method in a utility class and call it when you need to.


Solution:5

You could write a wrapper class that does the casting on-demand when an element is fetched. This might make sense if the list is large and you want to delay the performance penalty until an element is actually used. On the other hand it would cast each element every time it is accessed, so if you will be accessing elements of the Vector repeatedly, this might be a bad idea.

In your existing code, you might as well construct the Vector with the correct capacity:

Vector<String> strings = new Vector<String>(objects.size());  

That might improve the efficiency since it won't have to repeatedly allocate more memory if your list is large.


Solution:6

You should avoid having a Vector<Object> in the first place if it's 'really' a Vector<String>. Object is a mistake in Java.

You'll get a compiler warning, and with good reason, but you can take the route of casting to a Vector first and then to a Vector<String>. That's O(1), and pretty stupid, as you can later end up with a line of code like String s = vector.get(1); giving a ClassCastException, if you're incorrect about the Vector<Object> only ever containing Strings.


Solution:7

You are trying to use a run time feature to remove a compile time feature; the generics <String> is getting stripped anyway.

As others have noted, it is far better to find the source of this Vector and defined it to be a Vector<String>. That way you will use your compiler's warnings about putting the "wrong" object into the Vector instead of finding out if something bad was placed in there during program execution.

One of the problems this code has is that when you are grabbing your Vector<String> from your Vector<Object>, the code might fail. From a debugging perspective, failing at a conversion step isn't very useful. It would be far better to fail at the insertion step, because then you would have the opportunity to react immediately to the issue, instead of letting it lie latent for other parts of the code to discover.

I understand that you are concerned with typing speed; but that's an odd metric. It is always faster to not convert something because it is typed correctly in the first place; and, typing speed should not be optimized because it is usually done so at the expense of readability, proper code structure, reasonable design, etc. If you have to type something a bunch of times, perhaps it is time to make an abstract base class, or use some other means to allow the writing of one copy of the required code.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »