迭代器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;
}
}
这是我的主要课程,我称之为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());
}
}
提前感谢您的帮助!
答案 0 :(得分:5)
在getNextCard()
方法中,每次调用它时都会创建一个迭代器。迭代器总是从索引0开始(虽然有一个listIterator(index)
方法),但你不应该需要它。
选项1:跟踪迭代器,每次都使用相同的迭代器。然而,这有一个重要的缺点,尚未被其他任何人指出。来自Javadoc:
此类的
iterator
和listIterator
方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除非通过迭代器自己的删除或者添加方法,迭代器将抛出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()
调用与调解器一样快 - 两者都是常数时间。)
答案 1 :(得分:3)
您需要保存cards.listIterator()
返回的迭代器。
您的代码每次都会创建一个新代码,这意味着您始终会获得第一个元素。
答案 2 :(得分: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();
}