Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ArrayList cast different types of objects

Status
Not open for further replies.

chrisw09

IS-IT--Management
Nov 23, 2005
22
US
I have 2 classes:

gun and machinegun which extends gun

I have 1 arraylist of both gun and machinegun objects. How can i get the objects back out of the arraylist and retain their type?

I'm trying to use an equals method that's in both classes but i only want to compare like classes. (machinegun wouldn't try to match to a gun, only another machinegun)
 
If you know what to expect when you index through the list, just cast them:

Code:
Gun zero = (Gun)myArrayList.get(0);
MachineGun one = (MachineGun)myArrayList.get(1);

If you don't know, you can just "shoot in the dark," so to speak, and try this:

Code:
MachineGun mg;
Gun g;
try{
 mg = (MachineGun)myArrayList.get(0);
}catch(ClassCastException)
{
 g = (Gun)myArrayList.get(0);
}

You should try casting as a MachineGun first since ALL the elements are Guns and you wouldn't throw an exception like you want.

'hope that helps.

Dave

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...east is east and west is west and if you take cranberries and stew them like applesauce
they taste much more like prunes than rhubarb does
[infinity]
 
Thanks Dave, helps a lot. Just curious though, is using try/catch the only way to handle this if i don't know which i'm getting?
 
I THINK so, but I'd better defer to others. I suppose that if the Gun object had a property called myType and you set it, upon creation, to either "Gun" or "MachineGun", then you could get every element in the ArrayList, casting it as a (Gun) and then check the myType value, going back to the ArrayList and re-casting the element if you found that it was actually a (MachineGun).

Probably other ways to do it as well.

Dave

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...east is east and west is west and if you take cranberries and stew them like applesauce
they taste much more like prunes than rhubarb does
[infinity]
 
Seems to me like the other is a more efficient solution especially when only working with 2 classes...

The only reason i ask is because others are going to see my code and i want to not do anything completly stupid... :)

thanks again.
 
Also you can use an Object's method to retrieve the class name of the object.

Code:
	Arraylist list= null;
	list.add(new MachineGun());
	list.add(new Gun());
	..
	..
   if(list.get(0).getClass().getSimpleName().equals("MachineGun")){
   //here you can safely cast in the right class
	   MachineGun mgun= (MachineGun )list.get(0);	
   }

 
Throwing exceptions for normal controlflow is discouraged, and should be avoided, if reasonable possible. (syntax error, btw.)

Code:
if (gun instanceof MachineGun)
{
        MachineGun mg = (MachineGun) gun;
        // do something with mg
}

But if you compare them, and if you're only interested in their type, you shouldn't use 'equals'.
And if you use equals, you should stick to the contract (especially: hashcode ()).

And if someone is extending MachineGun to GoldenMachineGun, the instanceof will return true too - so perhaps you need something like
[/code]
if (a.getClass ().equals (b.getClass ()))
Code:
If a machinegun can't be used as if it was a gun, its probably the wrong way to extend at all.
Perhaps better to implement a common interface 'shootable' or the like.

Hard to tell without knowing further details.

seeking a job as java-programmer in Berlin: [URL unfurl="true"]http://home.arcor.de/hirnstrom/bewerbung[/URL]
 
I knew there were more intelligent ways of doing it!

Dave

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...east is east and west is west and if you take cranberries and stew them like applesauce
they taste much more like prunes than rhubarb does
[infinity]
 
Spending too much time in writing - (and didn't get my codetags right - oh boy).

Well - myType is of course the most wrong thing you could do.
Java is a strong typed language, so you can tell your Object in a secure fashion, which type it is.

But in most cases you don't need to know which type it is, because the object knows itself (and sometimes better :) ) which type it is.

Perhaps you can let the object do its job.

seeking a job as java-programmer in Berlin:
 
No need to rub it in!

Well, that's what I get for answering without consulting the API! :)


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...east is east and west is west and if you take cranberries and stew them like applesauce
they taste much more like prunes than rhubarb does
[infinity]
 
I personally think that behind an instanceof operator there's a design problem.

What about separating them into two ArrayList?

Cheers,
Dian
 
stefan,

using the getClass() method, are you suggesting having a dummy object for testing purposes?

e.g.

Code:
MachineGun mgDummy = new MachineGun();
if(myArrayList.get(0).getClass().equals(mgDummy.getClass())
 machineGuns[nextMGindex] = (MachineGun)myArrayList.get(0);
else
 guns[nextGindex] = (Gun)myArrayList.get(0);

Dave

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...east is east and west is west and if you take cranberries and stew them like applesauce
they taste much more like prunes than rhubarb does
[infinity]
 
@LFI
No - I don't know the code and what is really going on. (Is there a machineGun available, to compare to?)

Like Diancecht said - if you need to distinct them, why do you put them in the same collection?

Concrete advice would need more concrete knowledge.

seeking a job as java-programmer in Berlin:
 
Like stefanwagner said, it's tough to offer advice here without knowing your code's intention.

If you're simply using the ArrayList to hold any type of Gun, then why not extract all common behavior into an inteface, then use generics to type your ArrayList ie

Code:
public interface Gun
{
   public void shoot();
   public void reload();
}

public class Pistol implements Gun
{
//pistol implementation
}

public class MachineGun implements Gun
{
//MachineGun implementation
}

and then you could use it like this:

Code:
public class War
{
   protected List<Gun> weapons;

   public War()
   {
       weapons = new ArrayList<Gun>();
   }

   public void attack()
   {
      for (Gun aGun : weapons)
      {
         aGun.shoot();
      }
   }

   public void addToArsenal(Gun aGun)
   {
       weapons.add(aGun);
   }
//etc, etc
}

IMO if you need to know specifically what kind of gun it is, then you have to keep it in it's own List.
 
I wound up using the following to solve my problem:
Code:
if(list.get(0).getClass().getSimpleName().equals("MachineGun")){

I wish this app was something cool like a game but in reality it is a catalog for guns. I needed to be able to load a list of inventory items and run comparisions based on type of gun and so forth...

thanks for all the help
 
Thanks for the update! Man, I love closure!

Dave

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...east is east and west is west and if you take cranberries and stew them like applesauce
they taste much more like prunes than rhubarb does
[infinity]
 
If you're implementing a catalog, I still think you shouldn't put all kind of items in the same list, but categorize it.

Cheers,
Dian
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top