使用next()调用ArrayList的下一次迭代

iva*_*meh 2 java arraylist next

迭代器next()有点麻烦.似乎无法让它正常工作.我一直在研究这段代码,所以我觉得另一组眼睛会有所帮助.

这是我的deck类,它创建了一个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; 
}
}
Run Code Online (Sandbox Code Playgroud)

这是我的主要类,我称之为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());
    }

}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助!

mdi*_*ker 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));
}
Run Code Online (Sandbox Code Playgroud)

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