在Java中使用ArrayLists进行转换

时间:2008-12-11 06:09:35

标签: java casting arraylist

抱歉,我认为这是一个继承问题:它一直是一个ArrayList问题!

好的,我的问题比我想象的更具体。所以我有两个班级。卡片和区域。区域是持卡的盒子。

Zone,ZoneList和ZoneMap的前两个子类是存储卡的两种不同方式。其他子类,如Hand和PokerHand,有自己特定的方式处理他们存储的卡片。

如果它变得复杂,那么Card也有子类,比如PokerCard,而ZoneList和ZoneMap的子类就是为了组织它们。

所以在ZoneList中我有protected ArrayList<Card> cardBox;而在PokerHand中,由于PokerCard是一张卡,我预计能够宣布cardBox = new ArrayList<PokerCard>();。我得到的错误是,当涉及到ArrayLists时,我显然无法在Card和GangCard之间施放......所以我试图通过在PokerHand中重新声明cardBox为private ArrayList<PokerCard> cardBox;来解决这个问题,但这导致了隐藏这是在扰乱我的计划。

真的,问题是关于在ArrayLists之间进行转换? Java告诉我我不能,所以关于我怎么做的任何想法?

Ž。

6 个答案:

答案 0 :(得分:19)

Marc和kolstae在如何解决问题方面给出了很好的答案,但我认为值得解释为什么你的原始代码不起作用。

为了简化问题,我倾向于将问题放在水果方面。假设我们有:

List<Banana> bananaBunch = new ArrayList<Banana>();
List<Fruit> fruitBowl = bananBunch;
fruitBowl.add(new Apple());

如果这是允许的话,我们最终会在一堆香蕉中加入苹果,这显然是一件坏事。那么,问题出在哪里?第一行必须没问题,第三行必须没问题 - 你可以添加任何种类的水果到List<Fruit> - 所以问题必须在第二行。这就是被禁止的,正是为了避免这种问题。

这有帮助吗?

答案 1 :(得分:11)

如果我理解正确,您应该声明:

public class ZoneList<T extends Card> {
   protected List<T> cardBox;
}

public class PokerHand extends ZoneList<PokerCard> {
   public PokerHand() {
      cardBox = new ArrayList<PokerCard>();
   }
}

答案 2 :(得分:10)

首先,使用getter / setter方法通常比直接访问属性更好,特别是如果你要进行大量复杂的继承。

对于泛型问题,您可以尝试将超类(或顶级接口/抽象类)中的cardBox getter定义为:

protected ArrayList<? extends Card> getCardBox();

这样你就可以在子类中挖掘它并让它们返回任何类型的Card子类的列表。

答案 3 :(得分:8)

一种方法是首先转换为ArrayList:

ArrayList<Card> cards = (ArrayList<Card>)(ArrayList<?>) (pokerCardObjects);

另一种没有铸造的替代品:

使用流:

ArrayList<Card> cards = pokerCardObjects.stream().collect(Collectors.toCollection(ArrayList::new);

或者创建一个新的ArrayList:

ArrayList<Card> cards = new ArrayList<>(pokerCardObjects);

答案 4 :(得分:6)

如上所述,您无法将ArrayList<PokerCard>投射到ArrayList<Card>,但可以将ArrayList<PokerCard>投射到ArrayList<? extends Card>。或者更好地使用List<? extends Card>作为返回值,因为您可能无论如何都不依赖于ArrayList实现:

protected ArrayList<? extends Card> getCardBox();

至于评论中的问题,构造应该如您所述:List<? extends Card> list = new ArrayList<Card>();。您可能需要填写列表,因此方法可能是这样的:

protected ArrayList<? extends Card> getCardBox() {
    List<Card> list = new ArrayList<Card>();
    list.add(pokerCard1);
    list.add(pokerCard2);
    return java.util.Collections.unmodifiableList(list);
}

答案 5 :(得分:1)

这将取决于Zonelist中Arraylist上的访问控制。我从调试器声明中得出的假设是它没有标记,公共或受保护。子类可以通过定义具有相同名称的变量来“隐藏”它有权访问的父类变量。您还可以使用this关键字来引用特定对象实例,并使用super关键字来引用父级。

以下是Java中基本访问控制的一个很好的链接:

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

您可能还会找到有帮助的

http://java.sys-con.com/node/46344