Как перебрать список объектов с определенной переменной? - PullRequest
0 голосов
/ 08 февраля 2019

Итак, у меня есть класс Deck, который содержит список колод, который создает 52 объекта Card и сохраняет их в списке массивов.Я могу перебирать этот список колод, используя показанный мной итератор, но теперь я хочу знать, как я могу изменить итератор для перебора списка колод для определенных переменных.Например, я просто хочу перебрать все пики или всех королей.Спасибо.

fyi: DeckIterator находится в классе Deck, я просто не знал, как отформатировать код в стеке.Извинения.

    public class Card implements Serializable, Comparable<Card> {    
        static final long serialVersionUID = 100;

        Suit suit;
        Rank rank;

        public Card(Rank rank, Suit suit){
            this.rank = rank;
            this.suit = suit;
        }
    }

    public enum Rank {
        TWO(2), THREE(3), FOUR(4), FIVE(5), 
        SIX(6), SEVEN(7), EIGHT(8), NINE(9),
        TEN(10), JACK(10), QUEEN(10), KING(10), ACE(11);

        int value;

        public static Rank valuesList[] = Rank.values();

        Rank(int value){
            this.value = value;
        }

        public int getValue() {
            return this.value;
        }

        public Rank getNext() {
            if (this.value == 11) {
                return valuesList[0];
            } else {
                return valuesList[ordinal() + 1];
            }
        }

        public int getOrdinal() {
            return ordinal();
        } 
    }

    public enum Suit {
        CLUBS, DIAMONDS, HEARTS, SPADES;

        public static Suit suitsList[] = Suit.values();

        public Suit randomSuit() {
            Random random = new Random();
            return suitsList[random.nextInt(4)];
        }
    }

    private class DeckIterator<Card> implements Iterator<Card> {
        private final Deck deck;
        private int pos = 0;

        public DeckIterator(Deck deck) {
            this.deck = deck;
            pos = 0;
        }

        @Override 
        public boolean hasNext() {
            return pos < deck.size();
        }

        @Override 
        public Card next() {
            return (Card) deck.deck.get(pos++);
        }

        @Override
        public void remove() {
            deck.deck.remove(pos);
        }
    }

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Я просто хочу пройтись по всем пикам или всем королям.

Вот и мы.

new DeckIterator(deck, card -> Rank.KING.equals(card.getRank()));
new DeckIterator(deck, card -> Suit.SPADES.equals(card.getSuit()));

Я полностью согласен с ответом @ rzwitserloot,и расширит свой пост с помощью моего итератора, которому требуется Predicate для формирования другого итератора, который работает только с выбранными элементами.

class DeckIterator implements Iterator<Card> {

    private final Iterator<? extends Card> iterator;

    public DeckIterator(Deck deck, Predicate<Card> predicate) {
        iterator = deck.deck.stream().filter(predicate).iterator();
    }

    @Override
    public boolean hasNext() {
        return iterator.hasNext();
    }

    @Override
    public Card next() {
        return iterator.next();
    }

    @Override
    public void remove() {
        iterator.remove();
    }

}
0 голосов
/ 08 февраля 2019

Вы не можете;не с этой структурой данных.У вас есть несколько вариантов:

  1. повторять все, но прервать эту итерацию сверху, если она не соответствует вашему требуемому состоянию.Например:

    for (Card card : deck) {
        if (card.getRank() != Rank.ACE) continue;
        /* code to deal with aces here */
    }
    
  2. Для фильтрации используются потоковые конструкции API.Вы не включили свой класс Deck в свою пасту, но, предполагая, что deck.deck является своего рода java.util.List, вы можете, например, сделать:

    deck.deck.stream().filter(x -> x.getRank() == Rank.ACE).iterator()
    

, который даст вамитератор, который перебирает только тузы.

...