2013-04-26 2 views
2

Имея немного проблем с итератором next(). Кажется, он не работает правильно. Я работал над этим кодом некоторое время, поэтому я думал, что другой набор глаз поможет.Использование следующей() для вызова следующей итерации ArrayList

Это моя колода класс с создает список объектов карты, я пытаюсь сделать метод, чтобы захватить следующую карту в списке, начиная с первого:

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()); 
    } 

} 

Заранее благодарим за любую помощь!

+3

Любите свой бесконечный цикл subtil в 'getNextCard()'! –

+0

похоже, что вы каждый раз получаете новый итератор – Dan

ответ

4

В вашем методе 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

Еще не пробовал, потому что мне нужно идти на работу, но ваша вторая альтернатива - это то, как я собираюсь это сделать. Благодаря! – ivanthemeh

+0

Да, это было бы желательно. Удачи! – mdierker

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(); 
} 
+0

Просто попробовал эту строку кода, и он все равно печатает то же самое. – ivanthemeh

+0

@NotaNoobForever Да, я ошибся. Я исправил оператор 'return' с правильным кодом. – Laf

3

Вы должны сохранить итератор, возвращаемый cards.listIterator().

Ваш код создает новый каждый раз, что означает, что вы всегда получаете первый элемент.

Смежные вопросы