Casting between ArrayLists in Java

后端 未结 6 632
故里飘歌
故里飘歌 2020-12-15 11:56

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

Ok, my problem is more specific than I thought. So I have two families of

相关标签:
6条回答
  • 2020-12-15 12:21

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

    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<Card> cards = new ArrayList<>(pokerCardObjects);
    
    0 讨论(0)
  • 2020-12-15 12:29

    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>();
       }
    }
    
    0 讨论(0)
  • 2020-12-15 12:40

    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 this keyword to refer to the particular object instance and super keyword to refer to the parent.

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

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

    This you might also find helpful

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

    0 讨论(0)
  • 2020-12-15 12:41

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

    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.

    Does that help at all?

    0 讨论(0)
  • 2020-12-15 12:41

    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:

    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:

    protected ArrayList<? extends Card> getCardBox() {
        List<Card> list = new ArrayList<Card>();
        list.add(pokerCard1);
        list.add(pokerCard2);
        return java.util.Collections.unmodifiableList(list);
    }
    
    0 讨论(0)
  • 2020-12-15 12:42

    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.

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

    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.

    0 讨论(0)
提交回复
热议问题