具有各种类型对象的Java ArrayList
我有具有各种类型对象的Java ArrayList,java,list,iteration,Java,List,Iteration,我有CardType1和CardType2,它们扩展了Card,还有一个区域,该区域有一个ArrayList。此数组将填充CardType1和CardType2对象,但我最终需要访问它们,如下所示: for (CardType1 card : this.cards) { ... 概述: public class Area { List<Card> cards = new ArrayList<Card>(); .. } public class Car
CardType1
和CardType2
,它们扩展了Card
,还有一个区域
,该区域有一个ArrayList
。此数组将填充CardType1
和CardType2
对象,但我最终需要访问它们,如下所示:
for (CardType1 card : this.cards) { ...
概述:
public class Area {
List<Card> cards = new ArrayList<Card>();
..
}
public class Card {..}
public class CardType1 extends Card {..}
public class CardType2 extends Card {..}
公共类区域{
列表卡=新的ArrayList();
..
}
公共类卡{..}
公共类CardType1扩展卡{..}
公共类CardType2扩展卡{..}
如何仅迭代我的
列表卡
列表中的一个子类型?您将只能作为卡
迭代每个项目。如果您能够使用CardType1
进行迭代,那么当您遇到CardType2类型的卡时,就会出现错误
对于所需内容,您必须检查card
是否为CardType1
或CardType2
的实例,然后适当地强制转换card
:
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
}
}
您不能这样做,因为卡中对象的类型是
Card
,而不是CardType1
:
for(CardType1 card : this.cards){ ...
但是,您可以执行以下操作:
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
}
}
我在这里所做的,是像您一样迭代卡片(除了我的类型是除对象
之外最通用的类型)。然后,我使用instanceOf
操作符检查卡的类型是CardType1
还是CardType2
,并将其强制转换为该类型,然后处理它。ArrayList cards=new ArrayList();
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
}
}
添加(新的CardType1());
添加(新的CardType2());
对于(卡片:this.cards){
//卡可以是扩展卡的任何东西,即CardType1、CardType2
if(卡类型1的卡实例){
//做些什么
}
else if(CardType2的卡实例){
//做2件事
}
}
多米尼克和内森的答案是正确的。如果您使用番石榴,您可以使用以下快捷方式:
for (CardType1 card : Iterables.filter(cards, CardType1.class)) {
...
}
从文件中:
返回未筛选
中类类型
的所有实例。返回
iterable具有类为类型
或类型
的子类的元素
到目前为止还不错,问题是什么?你在哪里需要这样的访问权限?如果有一个异构列表比没有异构列表更有意义的话,那么可以跳出框框来考虑,将arraylist分区,这样可以额外存储一个pivot元素,并将该元素之前的所有内容保留为CardType1类型,之后的所有内容保留为CardType2类型。这需要在每次插入和删除操作中对arraylist进行排序和更新,但这将节省您迭代不需要的元素的时间。这是一个很好的解决方案@G.Bach,因为它避免了
instanceof
和isAssignableFrom
调用。@Brian确实如此,不过,我不知道那些操作员是否很慢。它还避免了对他实际上不想处理的元素进行迭代。这是否适合他,将取决于他是否频繁地更改arraylist,或者特定类型的卡的迭代次数是否很大。不错,但是每次迭代都会使用此调用过滤器吗?我的java已经生锈了。+1,它只对整个迭代器调用一次filter
,但是filter
基本上会对给定迭代器的每个成员调用instanceof
。对于任何足够复杂的项目,番石榴都是必须的:)@DominicBou Samra不确定我是否理解您的问题-调用将委托给迭代器。filter
,它返回一个自定义迭代器
,该迭代器跳过不可分配给该类型的元素。