Java 中 ArrayList 之间的转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/358546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:49:08  来源:igfitidea点击:

Casting between ArrayLists in Java

javacastingarraylist

提问by Ziggy

Sorry, I thought this was an inheritance question: it was an ArrayList question all along!

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

Ok, my problem is more specific than I thought. So I have two families of classes. Cards, and Zones. Zones are boxes for holding card.

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

The first two subClasses of Zone, ZoneList and ZoneMap are meant to be two different ways of storing Cards. Further subclasses, such as Hand, and PokerHand, have their own specific ways of dealing with the cards they store.

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

Where it gets complicated is that Card also has subClasses, such as PokerCard, and that the subclasses of ZoneList and ZoneMap are meant to organize those.

复杂的地方在于 Card 也有子类,例如 PokerCard,而 ZoneList 和 ZoneMap 的子类就是用来组织这些子类的。

So in ZoneList I have protected ArrayList<Card> cardBox;and in PokerHand I expected to be able to declare cardBox = new ArrayList<PokerCard>();since PokerCard is a Card. The error I am getting is that I apparently can't cast between Card and GangCard when it comes to ArrayLists... So I was trying to fix this by just redeclaring cardBox as private ArrayList<PokerCard> cardBox;inside PokerHand, but that resulted in the hiding that was bugging up my program.

所以在 ZoneListprotected ArrayList<Card> cardBox;和 PokerHand 中,我希望能够声明,cardBox = new ArrayList<PokerCard>();因为 PokerCard 是一张卡片。我得到的错误是,当涉及到 ArrayLists 时,我显然无法在 Card 和 GangCard 之间进行转换......所以我试图通过将 cardBox 重新声明为 PokerHandprivate ArrayList<PokerCard> cardBox;内部来解决这个问题,但这导致隐藏被窃听我的程序。

SO really, the question is about casting between ArrayLists? Java tells me I can't, so any ideas on how I can?

所以真的,问题是关于 ArrayLists 之间的转换?Java 告诉我我不能,所以有什么想法可以吗?

z.

z。

采纳答案by refrus

If I understand you correctly, you should probably declare:

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

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

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

回答by Scanningcrew

This is going to depend on what the access control is on the Arraylist in Zonelist. My assumption from the debugger statement is that it is either unmarked, public, or protected. A subclass can "Hide" a parent class' variable it has access to by defining a variable with the same name. You can also use thiskeyword to refer to the particular object instance and superkeyword to refer to the parent.

这将取决于Zonelist. 我对调试器语句的假设是它是未标记的、公共的或受保护的。子类可以通过定义具有相同名称的变量来“隐藏”它有权访问的父类的变量。您还可以使用this关键字来引用特定的对象实例,使用super关键字来引用父对象。

Here is a good link on basic access control in Java:

这是关于 Java 基本访问控制的一个很好的链接:

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

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

This you might also find helpful

这可能对您也有帮助

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

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

回答by Marc Novakowski

First of all, it's usually better practice to use getter/setter methods than accessing properties directly, especially if you're going to be doing a lot of complicated inheritance.

首先,与直接访问属性相比,使用 getter/setter 方法通常是更好的做法,尤其是当您要进行大量复杂的继承时。

As for the generics problem, you could try defining the cardBox getter in the superclass (or top-level interface/abstract class) as:

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

protected ArrayList<? extends Card> getCardBox();

That way you can ovverride it in subclasses and have them return a list of any type of subclass of Card.

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

回答by Jon Skeet

Marc and kolstae have given good answers in terms of how to get around the problem, but I think it's worth explaining whyyour original code doesn't work.

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

To simplify matters, I tend to put the problem in terms of fruit. Suppose we have:

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

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

If this is allowed, we end up with an apple in a bunch of bananas, which is obviously a bad thing. So, where is the problem? The first line has to be okay, and the third line has to be okay - you can add any kind of fruit to List<Fruit>- so the problem has to be in the second line. That's what's prohibited, precisely to avoid this kind of issue.

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

Does that help at all?

这些帮助有用?

回答by Markus

As stated, you cannot cast ArrayList<PokerCard>to ArrayList<Card>, but you can cast ArrayList<PokerCard>to ArrayList<? extends Card>. Or better use List<? extends Card>as your return value, because you probably don't rely on the ArrayList implementation anyway:

如前所述,您不能强制转换ArrayList<PokerCard>ArrayList<Card>,但可以强制转换ArrayList<PokerCard>ArrayList<? extends Card>。或者更好地List<? extends Card>用作您的返回值,因为您可能无论如何都不依赖 ArrayList 实现:

protected ArrayList<? extends Card> getCardBox();

As for your question in the comment, the construction should work as you described: List<? extends Card> list = new ArrayList<Card>();. You probably have to fill your list, so the method is probably something like this:

至于您在评论中的问题,构造应该按照您的描述工作: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);
}

回答by Steven Lizarazo

One way to do that is by casting to ArrayList first:

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

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

Another alternatives without casting:

没有铸造的另一种选择:

With streams:

使用流:

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

Or creating a new ArrayList:

或者创建一个新的 ArrayList:

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