Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine the type of object an ArrayList iterator will return next?

I have an ArrayList and I am using an iterator to run through it. I need to find out what type of object is next:

Iterator vehicleIterator = vehicleArrayList.iterator();

while(vehicleIterator.hasNext())
{
     //How do I find the type of object in the arraylist at this point
     // for example, is it a car, bus etc... 
}

Thanks

like image 417
Dan Avatar asked Jan 31 '10 23:01

Dan


4 Answers

Object o = vehicleIterator.next();
if (o instanceof Car) // Is a car
if (o instanceof Bus) // ...
like image 141
sinuhepop Avatar answered Oct 22 '22 19:10

sinuhepop


Firstly, get some generics in there. They have been in Java since 2004. Even the version of Java SE that introduced them has completed its End of Service Life period.

(As @finnw points out, I was forgetting about poor old Java ME. If you have to use Java ME then you will need to eschew generics and cast (but not instanceof often) until it (including deployed devices) makes it into 2004.)

Using instanceof and casting tends to indicate poor design. It would probably better to place into the list an object with an interface the client code can use without tests, and implementations that map to different behaviour for each "real" target of the list. "Every problem in computer science can be solved by adding another level of indirection" ["... except too many levels of indirection."]

like image 30
Tom Hawtin - tackline Avatar answered Oct 22 '22 18:10

Tom Hawtin - tackline


One way is to use the getClass() method.

Object obj = vehicleIterator.next();
Class type = obj.getClass();  
System.out.println("The type is: " + type.getName());

However, if you're explicitly checking class type there's almost always a better way to write your code using polymorphism or some other OO principle. Code that checks type like this, or using instanceof, would certainly have to be changed if additional types of cars are added.

Without having more information about what you're doing with the type, I'd suggest you have a base type Vehicle that Car, Bus, etc. all inherit from. Give your vehicles the methods they need (override the ones you need to) then just call those methods in your loop.

like image 45
Bill the Lizard Avatar answered Oct 22 '22 20:10

Bill the Lizard


Since you want the class of the next element rather than the current one, consider using a peeking iterator implementation.

Then you can use a loop condition like:

while (vehicleIterator.hasNext() &&
       ForkLiftTruck.class.isAssignableFrom(vehicleIterator.peek().getClass())) {
    vehicle forkLiftTruck = (ForkLiftTruck) vehicleIterator.next();
    // ...
}
like image 37
finnw Avatar answered Oct 22 '22 20:10

finnw