0

This method is supposed to return true if four different numbers in the array are all equal. But whenever I try to run it with 4 equal numbers, I get an error that says:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Assignment4.containsFourOfaKind(Assignment4.java:93)
at Assignment4.main(Assignment4.java:16)

public static boolean containsFourOfaKind( int hand[] ){ 
    for (int i = 0; i < 5; i++) {
        if (hand[i    ] == hand[i + 1] &&
            hand[i + 1] == hand[i + 2] && 
            hand[i + 2] == hand[i + 3]
        ) {
            return true;
        }
    }
    return false;
}

How can I fix this?

user2004685
  • 8,721
  • 4
  • 29
  • 49
  • You are looping from 0 to 4. When you get to `i == 2`, what is the value of `i+3` in the `if` statement? – Jim Garrison Feb 14 '16 at 02:53
  • If(hand[i] != hand[i + 1]) return false; When the loop terminates you know all the cards must be equal so you can return true. Your loop control needs to be set accordingly for this to work. – Feek Feb 14 '16 at 02:58

8 Answers8

1

When you run your loop from (i=0; i<5;...) you are checking five values... In your if statement you are looking at hand[i] == hand[i+1] && hand[i+1] == hand[i+2] && hand[i+2] == hand[i+3]. This means that during the iteration when i=4 you are trying to access hand[4] through to hand[7].

I suspect your array, hand, doesn't have that many elements.

David Hoelzer
  • 14,530
  • 4
  • 39
  • 61
1
public static boolean containsFourOfaKind(int hand[]){
  for(int x=0; x < hand.length; x++){
    for(int y=0; y < hand.length; y++){
      if(y!=x){
        if(hand[x]!=hand[y]){
           return false;
        }
      }
    }
  }
  return true;
}

You were going outside the index using the +1 within the loop. The above code checks to see if all of the elements in the array are the same.

Joel Holmes
  • 741
  • 8
  • 21
1

While others have addressed the ArrayIndexOutOfBoundsException quite clearly, I'd like to propose another method that uses no indexes:

    private boolean isArrayEqual(int[] array) {
        Arrays.sort(array);  //Sort array to place four of a kind in sequence

        int[] setOfFour = Arrays.copyOfRange(array, 0, 4);  //Copy first four values
        int[] compareArray = new int[4];

        Arrays.fill(compareArray, setOfFour[0]);  //Make an array containing only first value
        if (Arrays.equals(compareArray, setOfFour)) {  //Test if first four are equal
            return true;
        } else { //Test is last four are equal
            setOfFour = Arrays.copyOfRange(array, 1, 5);  //Copy of last four values
            Arrays.fill(compareArray, setOfFour[0]);
            return Arrays.equals(compareArray, setOfFour);
        }
    }

You create a second array which is filled with one of the values from the array in question (any value will do - I picked the first one). Then just see if the arrays are equal. Done.

rothloup
  • 998
  • 8
  • 21
  • How can this detect 4 of a kind in a hand of 5? It looks like this can only detect that all numbers are equal - so: 5 of a kind. – Erwin Bolwidt Feb 14 '16 at 03:38
  • @ErwinBolwidt: You are correct, I misread the question. I've edited my answer to check for 4 of a kind. – rothloup Feb 14 '16 at 03:54
1

Most answers only address the ArrayIndexOutOfBoundsException, but they don't address that your original code wasn't detecting for of a kind. It was trying to detect four-in-a-row. Imagine a hand {3, 0, 3, 3, 3}: even if your code didn't cause the ArrayIndexOutOfBoundsException, it still would say that this wasn't four-of-a-kind, although it clearly is.

You need code that actually counts how many of-a-kind there are and then check if it is four or more out of the total hand. (In a typical playing card deck you couldn't have more than 4 of a kind so you can check with == to 4 as well)

The code below is even agnostic to the number of cards in a hand, although from your code above it looks like your hand size is 5 (which is very typical in poker)

public static boolean containsFourOfaKind(int hand[]) {
    for (int i = 0; i < hand.length; i++) {
        int countOfKind = 0;
        for (int j = 0; j < hand.length; j++) {
            if (hand[i] == hand[j]) {
                countOfKind++;
            }
        }
        if (countOfKind >= 4) {
            return true;
        }
    }
    return false;
}

(Note that this is a native approach. You can optimize this further; for example if you look at this closely you'll see that i doesn't have to go any further than 0 and 1.)

Erwin Bolwidt
  • 28,093
  • 15
  • 46
  • 70
0
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{ 
    for(int i=0; i < hand.length - 1; i++) 
    {
        if(hand[i] != hand[i + 1])
            return false;
    }

    return true;
}

Going with your approach you could have had a simple check that was non-iterative that would just check to see if all the four cards were equal, however if you're going for an iterative approach then this is probably your best bet. Whenever you receive an arrayindexoutofbounds exception you always know that it has something to do with your arrays, and in your case there is only one spot that deals with arrays so it should be easy to visualize once you know what t he exception means.

A noniterative approach is as follows...

//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{ 
    if((hand[0] == hand[1]) && (hand[1] == hand[2]) && (hand[2] == hand[3]))
        return true;

    return false;
}

This can be used however it is not recommended.

Feek
  • 287
  • 2
  • 14
0

An approach that doesn't specifically target a hand, could be to target a larger group; where the array could be much larger than 4. In this case, you could have a loop add onto a map that counts how many times a certain "object" (literal meaning) is in that list:

public static boolean fourOfaKind(Integer[] hand) {
  HashMap<Integer,Integer> counts = new HashMap<Integer,Integer>();
  for(Integer i : hand) {
    if(counts.containsKey(i)) 
        {
            int count = counts.get(i);
            counts.put(i, ++count);
            if(count >= 4)
                return true;
        }
        else
            counts.put(i, 1);       
      }
  return false;
}
Raptor
  • 187
  • 1
  • 2
  • 11
TheBrenny
  • 519
  • 2
  • 17
0

simple code can be as follows, this will work for N number of element.

public static boolean containsFourOfaKind(int hand[]){

        for(int i=1; i < hand.length; i++){
            if(hand[i-1] != hand[i]){
                return false;
            }
        }
        return true;
    }
Bhushan
  • 537
  • 1
  • 5
  • 14
-1

In Java8 you can do it very easy:

private static boolean isEqualElements(int[] arr) {
    return Arrays.stream(arr).allMatch(value -> arr[0] == value);;
}
Bahramdun Adil
  • 5,435
  • 6
  • 31
  • 62