2

イテレータ next() に少し問題があります。適切に機能させることができないようです。私はしばらくこのコードに取り組んできたので、別の目が役立つと思っていました。

これは、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() を呼び出すメイン クラスであり、リストの最初のカードと次のカードを出力する必要があると考えていますが、最初のカードを 2 回出力しています。

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 に答える