user9010885
user9010885

Reputation:

How can you test and see if everything in a String[] is in an ArrayList<String>

I'm making a poker game, and I was trying to test and see if any player had a royal flush in their hand. Before I could test this, however, I came into a roadblock: I don't have a fast and simple way of testing each players' hands for the Ace, King, Queen, Jack, and ten in a suit.
This is my code so far:

private void findWinner() {
    // p1 hand
    List<String> p1hand = cards.subList(10, 15);
    p1hand.addAll(cards.subList(0, 2));
    System.out.println("Player 1's total hand is " + p1hand);
    // p1 hand
    List<String> p2hand = cards.subList(10, 15);
    p2hand.addAll(cards.subList(2, 4));
    System.out.println("Player 2's total hand is " + p2hand);
    // testing for royal flush
    String[] spadeRoyalFlush = {"Ace of spades", "King of spades", "Queen of spades", "Jack of spades", "10 of spades"};
    String[] heartRoyalFlush = {"Ace of hearts", "King of hearts", "Queen of hearts", "Jack of hearts", "10 of hearts"};
    String[] dimRoyalFlush = {"Ace of diamonds", "King of diamonds", "Queen of diamonds", "Jack of diamonds", "10 of diamonds"};
    String[] clubRoyalFlush = {"Ace of clubs", "King of clubs", "Queen of clubs", "Jack of clubs", "10 of clubs"};
    // p1
    boolean p1royalFlush = false;
    if(p1hand.contains(spadeRoyalFlush)) { // line 104
        p1royalFlush = true;
    }
    if(p1hand.contains(heartRoyalFlush)) {
        p1royalFlush = true;
    }
    if(p1hand.contains(dimRoyalFlush)) {
        p1royalFlush = true;
    }
    if(p1hand.contains(clubRoyalFlush)) {
        p1royalFlush = true;
    }
    if(p1royalFlush) {
        System.out.println("Player 1 got a royal flush with " + p1hand);
    }
    // p2
    boolean p2royalFlush = false;
    for(int i=0; i<p2hand.size(); i++) {
        if(p2hand.contains(spadeRoyalFlush)) {
            p2royalFlush = true;
        }
        if(p2hand.contains(heartRoyalFlush)) {
            p2royalFlush = true;
        }
        if(p2hand.contains(dimRoyalFlush)) {
            p2royalFlush = true;
        }
        if(p2hand.contains(clubRoyalFlush)) {
            p2royalFlush = true;
        }
    }
    if(p2royalFlush) {
        System.out.println("Player 2 got a royal flush with " + p2hand);
    }
} // line 165 is where I call this method

cards is an ArrayList of Strings that contains every name of each card (e.g. "Ace of spades", "3 of hearts", etc.)
When I run this code, I get the error:

Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$SubList.checkForComodification(Unknown Source)
at java.base/java.util.ArrayList$SubList.listIterator(Unknown Source)
at java.base/java.util.AbstractList.listIterator(Unknown Source)
at java.base/java.util.ArrayList$SubList.iterator(Unknown Source)
at java.base/java.util.AbstractCollection.contains(Unknown Source)
at poker.PlayGame.findWinner(PlayGame.java:104)
at poker.PlayGame.doEverything(PlayGame.java:165)
at poker.MainPoker.main(MainPoker.java:7)

I researched what that meant and I was astounded because as far as I could tell, I wasn't iterating over anything in my code.
This is the DoEverything method:

public void doEverything() {
    dealHands();
    throwCards();
    findWinner(); // line 165
}

This is the main method:

public static void main(String[] args) {
    PlayGame game = new PlayGame();
    game.doEverything(); // line 7
}

Upvotes: 0

Views: 107

Answers (2)

Stewart
Stewart

Reputation: 18313

I would use List.containsAll() as documented here.

Returns true if this list contains all of the elements of the specified collection.

String[] array = ...;
List<String> list = ....;
list.containsAll(Arrays.asList(array));

Reagrding the ConcurrentModificationException at line 104, you are calling contains() on p1hand, but p1hand is from cards.subList(10, 15).

We can't see where cards comes from. You have not posted the necessary code to debug that point. But see the answer from @devpuh for more detail on calling contains() on a sub-list.

Upvotes: 5

user8097737
user8097737

Reputation:

Be careful with List.subList(int fromIndex, int toIndex)!

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

(...)

The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

All changes on this create List will affect the original list!

And you get a ConcurrentModificationException as soon as you try to access a sublist when the original list was structural changed. (In your case you added a new element to the list cards)

Change

List<String> p1hand = cards.subList(10, 15);
p1hand.addAll(cards.subList(0, 2));

to

List<String> p1hand = new ArrayList<>(cards.subList(10, 15)); // create a new list
p1hand.addAll(cards.subList(0, 2));

And to check if the list contains all specific cards use

p1hand.containsAll(Arrays.asList(spadeRoyalFlush));

Upvotes: 1

Related Questions