简体   繁体   中英

Java ArrayList with various types of Objects

I have CardType1 and CardType2 that extends Card , and an Area that has an ArrayList of Card. This array will be filled with CardType1 and CardType2 objects, but I need to eventually access them like:

for (CardType1 card : this.cards) { ...

An overview:

public class Area {

    List<Card> cards = new ArrayList<Card>();
    ..
}

public class Card {..}

public class CardType1 extends Card {..}

public class CardType2 extends Card {..}

How can I iterate over only one of the subtypes in my List<Card> cards list?

You cannot do it this way, because the type of object in cards, is Card , not CardType1 :

for(CardType1 card : this.cards){ ...

You can however do this:

for(Card card : this.cards) {
    if (card instanceof CardType1) {
        CardType1 card1 = (CardType1) card;
        // do something with the card1
    } else {
        CardType2 card2 = (CardType2) card;
        // do something with the card2
    }
 }

What I am doing here, is iterating through the cards, as you were (except my type is the most general type to both besides Object ). Then I check if the card is of type CardType1 , or CardType2 , using the instanceOf operator and cast it to that type, then handle it.

You will only be able to iterate through each item as a Card . If you were able to iterate using CardType1 then you would have an error when you encountered a card of type CardType2.

For what you want you will have to check whether card is an instance of CardType1 or CardType2 and then cast card appropriately:

for (Card card : this.cards) {
    if (card instanceof CardType1) {
        CardType1 cardType1 = (CardType1) card;
        // do something with cardType1
    }
    else if (card instanceof CardType2) {
        CardType2 cardType2 = (CardType2) card;
        // do something with cardType2
    }
}

The answers by Dominic and Nathan are on the mark. If you're using Guava, you can use Iterables.filter(Iterable, Class) as a shortcut:

for (CardType1 card : Iterables.filter(cards, CardType1.class)) {
    ...
}

From the documentation:

Returns all instances of class type in unfiltered . The returned iterable has elements whose class is type or a subclass of type .

ArrayList<Card> cards = new ArrayList<>();
cards.add(new CardType1());
cards.add(new CardType2());

for(Card card : this.cards){ 
   // card can be any thing that extends Card. i.e., CardType1, CardType2
   if(card instanceOf CardType1){
       //do cardType1 things
    }
   else if(card instanceof CardType2){
      // do CardType2 things
      }


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM