ArrayIndexOutOfBoundsException when .length is zero - java

I got a java.lang.ArrayIndexOutOfBoundsException and I think it is because when nums.length gives me a zero (because there is nothing inserted in the parameter) the attribute I gave to the variable (-----.length -1------) will make it -1 when it gives me zero.
How should I make it not do this knowing that if I leave it .length without a -1 there will be an out of bounds exception on the other side of the array?
public boolean sameFirstLast(int[] nums) {
int lengthOfArray = nums.length - 1;
int thisIsHowLong = nums.length;
if (nums[0] == nums[lengthOfArray ] && thisIsHowLong > 0){
return true;
}
return false;
}
//always remember to return false in the end becuse if the top dosnt run then
//there will be no boolean returned and the method is not void so it has to return a //boolean
//ALWAYS REMEMBER TO SET nums.length - 1
//the .length method always starts from 1 and threfore will give you an extra space //that it will check for but we wont have anything in that space and then the compiler //will go to that space and will fond nothing to test with and gove an ERROR out of //bounds exeption because it is looking out of the array.

Your condition should look like
if(thisIsHowLong > 0 && nums[0] == nums[lengthOfArray ] )
Now if your first condition is false, second will never be checked.
And you want same.

You need to interchange the conditions.
if (thisIsHowLong > 0 && nums[0] == nums[lengthOfArray ]){ // This will prevent the exception.

Related

Wrap Around Grid - errors on east/west only

I have four methods that check whether or not a given grid location is next to an occupied location (value of 1). The grid is assumed to wrap around, ie, if in a 50x50 grid[0][1] is the given location and grid[49][1] is occupied, the method should return true/ My checkNorth and checkEast method are working fine, but I get an ArrayIndexOutofBoundsException: -1 error for either the south or west methods every time I run the program. I checked my math and I think it should work - am I using the modulo incorrectly, or am I missing something else?
EDIT: Clarified the wrapping criterion, word use correction.
boolean checkWest(int indexA, int indexB)
{
if (indexA-1 > 0)
{
if (grid[indexA-1][indexB] == 1)
{
return true;
}
}
if (indexA-1 < 0)
{
if (grid[(indexA-1)%width][indexB] == 1)
{return true;}
else return false;
}
return false;
}
I see a couple problems. First, Java arrays are zero-indexed, which means that the first element is at index 0. So it's okay to check grid[indexA-1][indexB] when indexA-1 is equal to 0. Second, you're not properly handling when indexA equals 0. Here is my implementation. I also simplified the logic a bit.
boolean checkWest(int indexA, int indexB)
{
if (indexA > 0)
return grid[indexA - 1][indexB] == 1;
else
return grid[width + indexA - 2][indexB] == 1;
}
EDIT: I'm pretty sure I butchered the math with the second return statement. It should be right now...

i do not understand the comparison

Im currently going over MIT courseware for java and am unsure why there is a piece of code involved. I tried removing the code to determine if it is necessary and it kept the program from running.
I have two arrays, one is names of runners, the other is their times. the goal is to find the index of the lowest (fastest) time and then also give the person with the second fastest time. i.e the command prompt will output john is the fastest and kate is the second fastest
the part i am confused about is "secondIndex == -1 ||" --- why is this here? if i remove it i get the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
public static int getSecondIndex(int[] values) {
int minIndex = getMinIndex(values);
int secondIndex = -1;
for(int i = 0; i < values.length; i++) {
if(i == minIndex){
continue;
}
if(secondIndex == -1 ||
values[i] < values[secondIndex]) {
secondIndex = i;
}
}
return secondIndex;
}
It will then evaluate values[secondIndex] which does not have an entry at index -1. The || short circuits from left to right so in the case of secondIndex = -1, values[secondIndex] will never be evaluated.
It's because the loop checks if the current runner's time is less than any time found so far, but when it checks the first runner there is no "fastest runner so far" to compare to. So the check first makes sure that secondIndex has been set at least once before. If it hasn't, the second part of the or statement will never get evaluated (called short-circuit evaluation).
The reason it's there is because of how indexOf works: it can only find things that live on index 0 or higher, so if it cannot find anything, it returns -1.
As such, we compare to -1 to see whether or not something was found at all. If it wasn't, we don't need to waste any more time on it:
if(thing.indexOf(otherthing) == -1) {
// the search failed
}
if it was, we can use the result to immediately look it by using the result of indexOf as an array index.
This condition (secondIndex == -1) is true in the case that secondIndex has not yet been found. Remember that since || is a short circuit operator, if the first condition is true, the second one will not be evaluated. Therefore, if secondIndex is -1, values[secondIndex] will never be evaluated (which is good, because doing so would cause the ArrayIndexOutOfBoundsException).

changing the order of condition in while loop crashes the program

changing the order of condition in while loop crashes the program. If I write like: while(a[in-1]>=temp && in>0), the program wont work. Why? The error is:ArrayIndexOutOfBoundsException: -1. The code below works until i make the above change.
public class ISort {
public int[] sort(int[] a){
int n=a.length;
for(int out=1;out<n;out++){
int temp=a[out];
int in=out;
while(in>0 && a[in-1]>=temp ){
a[in]=a[in-1];
in--;
}
a[in]=temp;
}
return a;
}
public static void main(String[] args){
int[] a={3,2,1,6,3,8,8,10,9};
ISort s=new ISort();
int[] res=s.sort(a);
for(int i=0;i<res.length;i++ ){
System.out.print(" "+res[i]+" ");
}
}
}
Because of Short-circuit evaluation.
If you write while(in>0 && a[in-1]>=temp), then if in <= 0, you don't evaluate the second part.
Why?
Because the result of false && anything is always false, so it's redundant to check the other side if the first side is already evaluated to false.
I think you got AarrayIndexOutOfBoundsException when you changed the order because in was <= 0 and you still tried to access a in a negative index. That's why when you want to access a method via some object and you're not sure whether the object is null, you sometimes do:
if(myVar != null && myVar.myMethod())
Because if in becomes 0 then in - 1 will be -1 and which is invalid index for array.
while(in>0 && a[in-1]>=temp) works because
When in > 0 is evaluated to false then due to short circuit a[in - 1] >=temp is not evaluated
while(a[in-1]>=temp && in>0) doesnt because
first a[in - 1] will be evaluated and when in reaches to 0 then in - 1 will be -1 and that will throw exception as -1 is not a valid index for an array and will throw ArrayIndexOutOfBoundsException.
Reason of not work of condition is that while(a[in-1]>=temp && i>0) array got negative index at in=0.
Consider the case where in = 0. The first thing the will be evaluated is a[in - 1] = a[-1] = IndexOutOfBounds. By checking the value of in first, you abort checking the array index if in is not greater than 0.

Java-How do I sequentially find the last occurrence of an element in an array that may not be filled?

I need to write a method that finds the index after the last occurrence of an element "item" in an array. I also have to find the index before the next largest item if item is not found. This is what I have so far.
public int findLast(E item)
int index = array.length - 1;
while (index >= 0 && comp.compare(item, array[index]) < 0) {
index--;
}
return index;
}
I believe that this will find the index if there is a match within the array, and the next largest value if a match is not found, unless the array is not full. If some positions in the array are not filled at the end of the array and still null, the call to the comparator gives me a NullPointerException. I need to be able to work around that. Any help would be appreciated!
EDIT:
Here is some sample output. It may not make too much sense as this is a very watered down version of a method in a larger data structure that I need to build called a ragged arraylist.
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.compareTo(Unknown Source)
at RaggedArrayList$StringCmp.compare(RaggedArrayList.java:360)
at RaggedArrayList$StringCmp.compare(RaggedArrayList.java:1)
at RaggedArrayList.findEnd(RaggedArrayList.java:149)
at RaggedArrayList.add(RaggedArrayList.java:170)
at RaggedArrayList.main(RaggedArrayList.java:309)
To avoid accessing an uninitialized instance, add an "OR" with array[index] == null to your loop condition, like this:
public int findLast(E item)
int index = array.length - 1;
while (index >= 0 && (array[index] == null || comp.compare(item, array[index]) < 0)) {
index--; // ^^^^^^^^^^^^^^^^^^^^^^^
}
return index;
}
A better approach would be passing the last index of the array where the data has been set. The best approach would be using collections that grow dynamically, rather than relying on arrays that cannot change in size.
You can use this this line :
int whereItIs = Arrays.asList(array).indexOf(item);

Can't figure out why recursion never resolves

My friend is making a minesweeper clone and he asked me to help with the part where when you click on a non-mine/non-number 'blank' square it reveals all adjacent blanks. The following is the code I wrote. I can't figure out why it never resolves.
My base case should be when the for loops completely execute and the if statement never returns true.
Is there something I'm missing?
This is in java, by the way. Also, I told him the whole slew of button state changing should be assigned to a method :p
public void revealAdjacentNulls(int r, int c)
{
int ir, ic;
//literal edge cases :P
int rmax = (r == 15) ? r : r + 1;
int cmax = (c == 15) ? c : c + 1;
//check all spaces around button at r,c
for(ir = (r==0) ? 0 : r-1; ir <= rmax; ir++){
for (ic = (c==0) ? 0 : c-1; ic <= cmax; ic++){
//if any are blank and uncovered, reveal them, then check again around the blanks
if (buttons[ir][ic].value == 0 && buttons[ir][ic].isCovered == false)
{
buttons[ir][ic].setEnabled(false); //number uncovered
buttons[ir][ic].setBackground(Color.blue);
buttons[ir][ic].setText(Character.toString(buttons[ir][ic].value));
buttons[ir][ic].isCovered = false;
revealAdjacentNulls(ir, ic);
}
}
}
}
Let's consider the case when r==0 and c==0, and let's assume that buttons[0][0].value == 0 and that buttons[0][0].isCovered == false.
The very first iteration of the loop will cause the function to call itself with the same arguments, 0, 0, and with unchanged state of value and isCovered. This will instantly lead to infinite recursion.
P.S. Check out the Wikipedia article for other flood fill algorithms.
Well for one thing, it will always keep recursing for revealAdjacentNulls(r, c). Your condition is that isCovered must be false - but then you're setting isCovered to false as well. Did you mean to write:
buttons[ir][ic].isCovered = true;
? Or possibly your check should be:
if (buttons[ir][ic].value == 0 && buttons[ir][ic].isCovered)
(It depends on what you mean by "is covered".)
Another case: if r == 15 then the loop will be from 14 (r - 1) to 15 (rmax). If your if statement is true, then there will be infinite recursion. The same applies to c.

Categories