views:

122

answers:

2

I have the following code in some app:

int lowRange=50;
int[] ageRangeIndividual = {6, 10, 18, 25, 45, 65, 90};
int index=0;
for (; index<ageRangeIndividual.length-1 && ageRangeIndividual[index]<=lowRange;index++);

I am getting an "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7" in the for line! even though I explicitly specify to break the cycle if index < last indexable item in the array!

This does not happen always, but after some time of running said program (lowRange varies each time the function is called)

What am I not seeing?

+2  A: 

The code you've posted doesn't throw an exception, on its own. In fact, your array bounds check is one off - you're being too conservative, unless you really don't intend to check the last value. It would normally just be

index < ageRangeIndividual.length

You say it happens eventually - do you have any other threads changing the value of index or ageRangeIndividual?

I presume you're about to use index in the next line - personally I'd find it clearer if this were wrapped up in a method:

// Rename to something more appropriate, perhaps
public static int findIndexOverMinimum(int[] values, int minimum)
{
    for (int i = 0; i < values.length; i++)
    {
        if (values[i] > minimum)
        {
            return i;
        }
    }
    return -1; // Or throw an exception, whichever is most appropriate
}

I really don't like for loops which have no body, and which use an existing variable for indexing. It's all perfectly valid, but it just feels wrong.

Jon Skeet
For the last part, it's useful if you break early in the loop and you want to check the index to see if that happened. That's a big reason I like python's `for/else` construct, it eliminates the need for most of that
Michael Mrozek
@Michael: I find that requiring the index later is *usually* an indication that refactoring will make it simpler. Not always, but usually. Or I keep a separate "bestIndex" or something like that. The iteration variable itself feels "temporary" somehow...
Jon Skeet
This way of using an iterative structure is an adaptation of a basic algorithm often used to find a value in a sequence. If the temp variable contains "nothing" it means that the value wasn't found.@Michael Mroze: As you probably know, the return statement in Jon's answer acts as a break.
James P.
A: 

An ArrayIndexOutOfBoundsException appears when you're referring to an array index value that exceeds it's length value minus 1 (you're basically fishing for something that isn't there).

In this case, index would need to reach 7 followed by an an access attempt for this to happen (exceeds 0-6). The expression ageRangeIndividual.length-1 would give 6 (number of elements in an array minus one) and the expression index<ageRangeIndividual.length-1 should evaluate to false. In turn the second expression after the && operator shouldn't be evaluated and so shouldn't trigger the Exception in the first place.

The only thing I can think of is whether the actual code you're testing is different or whether index<ageRangeIndividual.length-1 is being evaluated as intended. According to operator precedence ( http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html ) the substraction should be processed first.

James P.