2

迭代器 next() 有点麻烦。似乎无法让它正常工作。我已经在这段代码上工作了一段时间,所以我认为另一双眼睛会有所帮助。

这是我的甲板类,它创建了一个 Card 对象列表,我正在尝试创建一种方法来获取列表中的下一张 Card,从第一个开始:

package blackjack;

import blackjack.Card.Rank;
import blackjack.Card.Suit;
import java.util.*;

public class Deck {

public ArrayList<Card> cards = new ArrayList<>();
int i;
Card next;

public Deck() {
    initializeDeck();

}

public void printDeck() {
    for (Card c: cards)
        System.out.println(c);
}

private void initializeDeck() {
    for (Suit suit : Suit.values()) {
        for (Rank rank : Rank.values()) {
            cards.add(new Card(rank, suit));
        }
    }
}

public Card getNextCard() {
    if (cards.listIterator().hasNext() != true) {
        getNextCard();
    }
    else {
        next = cards.listIterator().next();
    }
      return next; 
}
}

这是我调用 getNextCard() 的主要课程,我认为它应该做的是打印列表中的第一张卡片,然后打印下一张卡片,但它正在做的是打印第一张卡片两次。

package blackjack;

import java.util.*;

public class BlackJack {

public static void main(String[] args) {
    Deck deck = new Deck();
    System.out.println(deck.getNextCard());
    System.out.println(deck.getNextCard());
    }

}

提前感谢您的帮助!

4

3 回答 3

5

在您的getNextCard()方法中,每次调用它时都会创建一个迭代器。迭代器总是从索引 0 开始(尽管有一个listIterator(index)方法),但你不应该需要它。

选项 1:跟踪迭代器,每次都使用相同的迭代器。但是,这有一个其他人尚未指出的重要缺点。来自 Javadoc:

此类iteratorlistIterator方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时候列表在结构上被修改,除了通过迭代器自己的 remove 或 add 方法之外,迭代器将抛出一个ConcurrentModificationException.

翻译:如果您在迭代器之外以任何方式修改列表(例如,通过在列表末尾添加卡片),那么您的迭代器会中断。这将我们引向选项 2:

选项 2:保留您上次返回的索引的计数器,并且每次都简单地返回。就像是:

public class Deck {

public ArrayList<Card> cards = new ArrayList<>();
Card next;
int currentCardIndex = -1;

/* The initialization stuff you have above */

public Card getNextCard() {

    currentCardIndex++;

    // If we're at the end, go back to the beginning
    if (currentCardIndex >= cards.size()) {
        currentCardIndex = 0;
    }

    return (next = cards.get(currentCardIndex));
}

最后是选项 3:(不建议):如果您真的想要,您可以在ConcurrentModificationException此时捕获并生成一个新的迭代器,但除非您需要一些特定于迭代器的功能,否则没有真正的理由。(get()调用与交互器一样快 - 两者都是恒定时间)。

于 2013-04-26T20:08:38.010 回答
3

您需要保存由cards.listIterator().

您的代码每次都会创建一个新元素,这意味着您始终会获得第一个元素。

于 2013-04-26T19:57:59.567 回答
0

您总是会得到第一张卡片,因为每次调用该getNextCard ()方法时都会创建一个新的迭代器。线

next = cards.listIterator().next();

将始终创建一个新的迭代器。你想要做的看起来像(假设你想在ListIterator每次到达牌组的最后一张牌时创建一个新实例):

private ListIterator<Card> myIterator = null;

public Card getNextCard() {
    if (myIterator == null || !myIterator.hasNext ()) {
        myIterator = cards.listIterator ();
    }

    return myIterator.next(); 
}
于 2013-04-26T19:57:57.577 回答