【问题标题】:Array list of objects just creates a reference to the same object java对象的数组列表只是创建对同一对象 java 的引用
【发布时间】:2019-06-20 16:12:09
【问题描述】:

我正在为学校写作业。 我正在制作一副简化的纸牌,您可以选择花色的数量和每个花色的纸牌数量。 (西装和等级)。我有一个创建单张卡片的 Card 类和一个创建一副卡片(一副卡片对象)的 DeckOfCards 类。我试图将卡片放入 ArrayList(在 DeckOfCards 构造函数内),但每次它只是创建对最近创建的卡片的引用。我花了几个小时试图弄清楚,但在任何搜索中都找不到答案。



public class DeckOfCards
{

    private int counter = 0;
    private ArrayList<Card> cardList = new ArrayList<>();

    public DeckOfCards(int rank, int suit)
    {
        for (int x = 0; x < suit; x++) // x is suit
        {
            for (int y = 0; y < rank; y++)  // y is rank
            {
                cardList.add(counter, new Card(x, y));
                counter++; // counter is position in ArrayList / deck
            }
        }
    }

    public String dealCard(int numOfCards)
    {
        // returns the card (numOfCards)
        return cardList.get(numOfCards).toString();
    }
}

/* Card Class and Constructor
public class Card
{
    private static int SUIT;
    private static int RANK;

    public Card(int suit, int rank)
    {
        this.SUIT = suit;
        this.RANK = rank;
    }

    public String toString()
    {
        return ("S"+ SUIT + "R" + RANK);
    }
}



Depending on the rank and suit the output should be

S1R1
S1R2
S1R3
.
.
.
S4R1
S4R2
S4R3

But the out put is always the last card created
S4R3

【问题讨论】:

  • 因为Card 类中的字段是静态的。所以它不是引用添加到卡片组中的最后一张卡片,而是您所有卡片的字段值都相同,因为您将它们声明为 static
  • 天哪,我真是太傻了。谢谢!

标签: java arraylist


【解决方案1】:

ArrayList.get(int index) 是你的问题。您的 dealCard 方法将相同的 numOfCards 变量(我假设在您的测试用例中为 1、2、3 等)作为列表中的索引。您应该做什么取决于您正在寻找的行为。

应该洗牌吗? 如果是这样,请查看this

发牌后是否应该从牌组中取出牌? 如果是这样,您应该使用ArrayList.remove(int index),它既可以从牌组中取出卡片,又可以同时归还卡片。

除此之外,您的方法应如下所示:

public String dealCard(int numOfCards)
{
    Card[] dealtCards = new Card[numOfCards]; //This could also be another ArrayList if you want, but unless you're going to be adding/removing cards from the returned object afterwards it shouldn't be necessary
    for(int i = 0; i < numOfCards; i++) {
        dealtCards[i] = cardList.get(i); //or cardList.remove(0);
    }
    return dealtCards; //Notice that this will return the same cards each time you call the method if you use cardList.get(i) unless you implement a cyclical counting variable outside of the method and use it inside the method.
}

【讨论】:

  • 他已经重写了toString() 方法,并且使用索引访问arrayList 没有问题 - 你甚至不知道他是如何调用这个方法的,因为他没有显示他的代码。更有可能是他的 Card 类中的静态字段有问题。
  • @michalk 你是对的toString() 位,我删除了我的答案的那部分。你也对,这些变量不应该是静态的,但return cardList.get(numOfCards).toString(); 绝对没有任何意义,除非numOfCardsnumOfCard 的错字。我现在意识到这是一个很大的可能性。
  • 是的,你这么说,numOfCards 是一个错字,它在一个循环中显示不同数量的卡片,因此我错误地将其命名为 numOfCards 而不是单数。主要问题是静态变量类型。你们人又好又快。感谢您的意见。
【解决方案2】:

如果您想在创建卡片时打印卡片,您只需从 Card() 构造函数中调用 toString() 方法...

...但是如果您希望从交易卡中打印它们,那么您需要使用 for 循环或通过递归调用(您可能已经在 dealCard 方法之外执行此操作)来索引数组列表中的每张卡。

我认为您只打印最新卡片的原因是因为您的参数 - 'numOfCards' 是您创建的卡片的“实际”数量 - 这也是您的数组列表中的最后一个索引,可能是您的原因只打印您最近创建的卡片。

PS 我认为您不需要使用计数器来表示您的数组列表的索引。使用 arraylist.add('object') 只是将 object 参数附加到列表的末尾。数组列表中已经有对象的索引,因此使用计数器排序会达到目的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多