While working on some java project I encountered this peculiar error:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 2
How can there be an index out of bounds exception? Index 1 means it tries to get the second element, Size 2 means there are 2 elements, so there shouldn't be a problem, no?
Context:
I have the following function:
public int howManyAgents(){
// cell is a class that can have 0 or multiple objects
// I get a list of cells that contain at least 1 agent
List<Cell> cellsWithAgents = getNonEmptyCells();
// initializing a counter
int agentsCount = 0;
for(int i=0; i<cellsWithAgents.size(); i++){
// For every cell in the list I add to the counter the number of
// agents that cell contains
agentsCount += cellsWithAgents.get(i).howManyAgents();
}
return agentsCount;
}
Now, the problem was that I got a null pointer exception at the line:
agentsCount += cellsWithAgents.get(i).howManyAgents();
I want to debug the code, but this function is called many times while the program is running and the null pointer exceptions comes up at different points in time (after 10 seconds after 1 minute after 5 minutes). So I tried to come up with a method to have e breakpoint when the cell is null so I came up with this code:
public int howManyAgents(){
// cell is a class that can have 0 or multiple objects
// I get a list of cells that contain at least 1 agent
List<Cell> cellsWithAgents = getNonEmptyCells();
// initializing a counter
int agentsCount = 0;
for(int i=0; i<cellsWithAgents.size(); i++){
int pass;
if (null == cellsWithAgents.get(i))
pass = 1; // breakpoint here
// For every cell in the list I add to the counter the number of
// agents that cell contains
agentsCount += cellsWithAgents.get(i).howManyAgents();
}
return agentsCount;
}
Of course, it is not the best method. The most logical way is jut to surround the code with try/catch and put the breakpoint there. The point is that the code above didn't work. It did not stop at the breakpoint but instead it threw the index out of bounds exceptions at the line:
if (null == cellsWithAgents.get(i))
Why? How can it be possible to throw an index out of bound exception if apparently the index is in bounds?
Edit: changed a mistake in copying the code
Update:
I have tried to see why the null pointer exception appears with a try/catch and put a breakpoint there. It seems that cellsWithAgents sometimes contains a null. This is, most probably because of concurrency as #rlinden stated.
About concurrency: there are some cells that can contain agents. There is a variable number of agents that can move between the cells. There is a special agent that tries to count how many moving agents there are (using this function).
So, only one agent (thread) can use this function, but multiple agents can modify cells (and thus mess with getNonEmptyCells() and howManyAgents() results).
Still, how it is possible to get index out of bounds with size 2 and index 1? It is not possible because of the concurrency, is it? Because only this thread can change the list cellsWithAgents. So, even if one of the elements in the list becomes null, the list still contains that number of pointers, so the size of the list cannot change. Or can it in some way that I miss?
And how can it be explained that the stack trace prints Index:1 Size: 2?
New Idea
Try changing the loop and see if the error persists:
int agentsCount = 0;
for(Cell cell : getNonEmptyCells()) {
if(cell != null) {
agentsCount += cell.howManyAgents();
} else {
System.out.println("Found a null cell");
}
}
I would like to see the code of the method getNonEmptyCells(). If your program is actually multithreaded and this function returns a fixed List that is changed at every interaction, then it is possible that changes in following executions have affected the previous, unfinished ones.
This is due to the fact that the line cellsWithAgents = getNonEmptyCells(); does not create a copy, but a reference to the return value of getNonEmptyCells(). So, if this method reuses the return object, it is possible that the first execution would believe there was two, but the concomitant thread changed the content size to less than 2.
The problem is, program is throwing exception at cellsWithType.get(i). What you can do is either put a breakpoint at if (null == cellsWithType.get(i)) and try debug it. Or change it to,
if (i >= cellsWithType.size())
pass = 1; // breakpoint here
Related
Actually I want to show the first element of arraylist in textfield1 and its next element in textfield 2 I want it to keep rotating whenever I press button. The problem is that it keeps showing the last element in both textfields
public class Teams
{
String[] P={"Hi","there","you"};
}
Teams tm=new Teams();
for(int j=0;j<=tm.P.length; j++){
textfield1.setText(tm.P[j]);
textfield2.setText(tm.P[j+1]);
}
You can perform an additional check (If-Else).
if textfield1's text is equals to the array[1] then
do swapping.
If it will be there. It will swap it. If not then that If check will be ignored.
This is the answer what I understood your question so far.
You should get the ArrayIndexOutOfBoundsException exception when you run this code. Your code will terminate with the exception.
According to your example tm.P.length is 3.
When j=2,
textfield1= there
textfield2= you
when j=3,
textfield1= you
and
textfield2.setText(tm.P[j+1]);
is getting the exception (ArrayIndexOutOfBoundsException)and terminate the flow since tm.P[4] (there is no such a location in the array)but textfield2 previous value is "you"
So your final result is
textfield1= you
textfield2= you
From what I get from your code :
public class Teams{
String[] P={"Hi","there","you"};
}
Another class
//Inside some function in another class
Teams tm=new Teams();
for(int j=0;j<=tm.P.length; j++){
textfield1.setText(tm.P[j]);
textfield2.setText(tm.P[j+1]);
}
The variable P in class Teams has length 3. So in the code snippet below the value of j changes from 0 to 3. In the case when the value of j is 2 the line
textfield2.setText(tm.P[j+1]);
should throw ArrayIndexOutOfBoundsException as the index j+1 i.e. 3 does not exist for P.
Also when the value of P is 3 both the lines
textfield1.setText(tm.P[j]);
textfield2.setText(tm.P[j+1]);
should throw an ArrayIndexOutOfBoundsException as the index of P is 3 for the first line and 4 for the second line.
Now since you have stated clearly in your comments that there is not exception being thrown, I feel that this code must be inside a try - catch block which catches Exception objects. Also this should explain why this kind of behaviour of show the last value of P in both text fields happen.
When j is 1, textfield2.setText(tm.P[j+1]) the text to this field is set to the last element "you". Now in the next loop when j attains the value 2 the first text field textfield2 gets set to the last element "you". But in the next line an exception is thrown so the line is not executed so the text of textfield2 remains to you.
finally when j is 3 the first line itself throws the exception so that the code after the first line is not executed and both textfield1 and textfield2 have text values "you" stored in them and that is what is displayed and results to the problem you have highlighted.
I am having a weird issue with java list. Please see the code below:
for ( int i=0; i < tripList.size(); i++ ) {
ModeChoiceTrip trip = tripList.get(i);
int newUniqueId = tripListIds[trip.uniqueId];
int newLinkedId = trip.linkedId >= 0 ? tripListIds[trip.linkedId] : -1;
int jointTripNum = trip.linkedId >= 0 && trip.tourType != TourTypes.SPECIAL_EVENT ? jointTripListIds[trip.linkedId] : 0;
trip.uniqueId = newUniqueId;
trip.linkedId = newLinkedId;
trip.jointTripNum = jointTripNum;
}
In the above code, the values in tripList seem correct but after executing a few iterations (up to i = 6), the values in tripList changes for all the positions.
I cannot provide the whole source code here but showing the snippet of the code where I have an issue.
I found that there are some duplicate trips in tripList. When one of the trips is changed, the copy of it (located at different position) is also changed.
I am guessing this piece of code is executed by multiple threads, Then there is every chance that List could be modified by another thread while this loop is going on.
you could try synchronizing the loop and see if issue gets resolved.
Also, you could try using for-each loop instead of the loop with counter.
for (ModeChoiceTrip trip : tripList) {
.....
}
The issues was the duplicate values in the list. Thus, when I update a value in list the copy to that value changes as well
You set the unique id to -1. So if the trip list id comes in as -1, you grab the index like tripListIds[-1]; which might be the second to the last item in the list.
I have been working on a few projects lately that use a flood fill on a 2D array to create a grid map for a game.
Part of the flood fill algorithm I am using grabs the neighboring "cells" in the grid and floods them if they are an open space and ignores them if they are not.
However, because I am grabbing neighbor cells, I am grabbing items from the array relative to the current cell like this: grid[y][x-1].
Obviously, when x == 0 an out of bounds error is thrown. In order to address this I have been using a conditional statement to check that the index I am accessing is in the array. Like this:
if(x - 1 >= 0){do what I need to that neighbor}
I know I can also address the error by using a try catch.
However, I am not sure which is the proper solution.
There are a few specific questions I have:
1) Does using the conditional method to prevent an error from occurring, require more overhead and create less efficiency? (I may be flooding thousands of cells)
2) How exactly does the catch block work? Is it conditionally checking for errors in the background some how?
I also made a very small demo code to show you exactly what I am talking about, just scaled down:
public static void main(String[] args) {
//declare our test array and initialize size 3
String [] testArray = new String[3];
//This is here for one of the methods I have been trying to avoid errors on
int indexAdjuster = 5;
//this the index of the array we are adjusting
int i = 0;
//now throw an error! uncomment to confirm there is an error if you want
//testArray[i-indexAdjuster] = "error";
//testArray[i+indexAdjuster] = "error";
//IGNORE the error with a try catch
try{
//this would result in an out of bounds exception below index 0 (-5 specifically)
testArray[0-indexAdjuster] = "error";
//this would result in an out of bounds exception above index 2 (5 specifically)
testArray[0+indexAdjuster] = "error";
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("There was an error, but I ignored it");
}
//PREVENT an error with a condition test
//it first checks if the adjusted index is at least 0
//then it checks if the adjusted index is less than the length of the array
if(i - indexAdjuster >= 0 && i + indexAdjuster < testArray.length){
//this would result in an out of bounds exception below index 0 (-5 specifically)
testArray[0 - indexAdjuster] = "This would be an error, but it is prevented";
//this would result in an out of bounds exception above index 2 (5 specifically)
testArray[0 + indexAdjuster] = "This would be an error, but it is prevented";
}else{
System.out.println("We just prevented the error");
}
System.out.println("Test Complete");
}
It depends, specifically on what you primary focus is: Speed or clean code.
If the error condition occurs rarely and the check is costly, catching an exception may be cheaper than checking beforehand. This conflicts the commonly accepted rule that catch blocks should not be used for regular flow control. Exceptions should be used to catch unexpected error conditions, an index outside an array is hardly unexpected.
The test can also be extracted into a separate method, making the code easier to read:
static boolean isValidIndex(String[] array, int i) {
return i >= 0 && i < array.length;
}
Or use a resilient access method:
static String getIndex(String[] array, int i) {
return i >= 0 && i < array.length ? array[i] : null;
}
(You may want to replace null with a constant value indicating an invalid value).
In your code you can simply use the getIndex() method for whatever index you calculated and act on the value it returns instead of the index. Same can be done for assigning to an index, if its appropiate to just ignore attempted assignments to non-existing indices:
static void setIndex(String[] array, int i, String value) {
if (i >= 0 && i < array.length)
array[i] = value;
}
The main issue you face is deciding if an out-of-bounds condition is just a normal case that has a reasonable default handling option or if it represents a real error that warrants aborting the method or program.
If its a real error condition, don't prevent it, don't catch it. Let it throw and bubble up the call stack. Whatever caller level initiated the whole action should be the one that responds to the execption. Its important to decide sensibly who is responsible for the handling, a deep-down detail method has often not enough information to make a reasonable decision what an error means - in those cases assign the responsibility to the caller (repeat until the caller can make the decision).
Using if statement to check your boundaries cause lots of overhead in each loop iteration.
I suggest you allocate a bigger array by 1 like:
String [] testArray = new String[3+1];
This cause that you don't need any if condition.
In response to your question about exception handling, it does not run any condition in background. It runs your code and after causing access violation determines you catch clauses.
I'm trying to do a homework assignment. I have to use dynamic programming to display whether the next person to move is in a win/loss state. I don't need help with the actual problem, I need help with an index out of bounds exception I'm getting that baffles me. I'm only going to paste part of my code here, because I only need the for loops looked at. I also don't want anyone in my class seeing all my code and copying it. If you need more data please let me know. So here is the code:
if(primeArray[x] == true){
for(int i = 1; i <= x; i++){
if(primeArray[i]== true){
newRowNumber = x - i;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
}
//COMPOSITE CASE FOR X!
else{
for(int k = 1; k <= x; k++){
if((primeArray[k] == false)){
newRowNumber = x - k;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
For some reason the if(primeArray[i] == true runs correctly, but I'm getting index out of bounds exception on if(primeArray[k] == false. The only difference between these two is the use of the variable k over i in the for loop.(the for loops are identical) I haven't used either variables anywhere else in my code. I have no idea why this occurs for one but not the other. In both cases, x remains the same number.
I am also getting an index out of bounds exception on the second minimum = dynaProgram[newRowNumber][columnNumber], while the first doesn't encounter an error. I know it's probably a stupid error, but I can't figure it out. If I change the 'k' for loop to k < x the index of out bounds exception in the if(primeArray[k] == false line goes away, but then it isn't correct. (The error on the second minimum = dynaProgram[newRowNumber][columnNumber] doesn't go away however.)
All this code is in a nested for loop which iterates through the rows and columns in the table to fill them in. If I remove the above code and just put dynaProgram[rowNumber][columnNumber] = 1 I don't have an issue, so I don't believe that is the problem.
When accessing an array of length 5 (for example)
int[] fred = new int[5];
the first element will be fred[0] and the last will be fred[4]
So when doing something like:
if(primeArray[i]== true){
Make sure that i is less than the array length. Using a value of i equal to the array length will throw an exception.
Hi
this code will return indexoutofboundsException and really I don't know why?
I want to remove those objects from pointlist which are as the same as an object in the list.
public void listOfExternalPoints(List<Point> list) {
System.out.println(list.size());
System.out.println(pointList.size());
int n = pointList.size();
for (int i = pointList.size() - 1; i >= 0; i--) {
for (int j = 0; j < list.size(); j++) {
if (pointList.get(i)==(list.get(j))) {
pointList.remove(i);
n--;
}
}
}
}
Also the out put of println will be :
54
62
Also the exception:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 60, Size: 60
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at ConvexHull.BlindVersion.listOfExternalPoints(BlindVersion.java:83)
thanks.
hey, you removed some elements from the list. So the list is smaller than it was at the beginning of the loop.
I suggest you to use:
pointList.removeAll(list)
Or an iterator.
When you do pointList.remove(i), you should break from the inner loop. Otherwise, it will try to index pointList.get(i), which you just removed, again on the next iteration of the loop, which is why are you getting the exception.
When arrayLists remove elements, that element is taken out, and all elements after it gets shifted down. So if you remove index 3 and there are only 4 elements, the new arrayList only has size 3 and you try to get index 3, which is out of bounds.
EDIT: A better way to do this is:
for(Point p : list) {
pointList.remove(p);
}
It will have the same efficiency, but more correct, I think. Remember that == compares references for the same object. Where as the remove method uses .equals to check for equality, which is what I assume you want.
pointList.remove(i);
This will decrease your pointList size. Hope this helps.
Removing the object from pointList will reduce its size. Therefore, in one iteration of the "for j" block, you may be removing two elements of PointList, shifting all other elements to the left. However, in the next iteration "i" will refer to an out of bounds location (60).
The problem is with the order of loop evaluation. You are only evaluating the length of pointList once, and never checking it again.
If you remove the last item from pointList, and you have not reached the end of list, then you will attempt to get() same item from pointList again and you will be reading off the end of the list, causing the exception. This is what shoebox639 noticed; if you break the inner loop after removing something, the decrement in the outer loop will fix the issue.
Because of the order of iteration, it is impossible to remove two elements from the same run through the loop- you're only considering the end of the list, so nothing beyond the current point in pointList is candidate for removal. If you were to remove two elements at once, it would be possible to shorten the list to a degree that the next i is off the list, but that can't happen here. Watch out for it in other, similar loops, though.
You may remove more then one element of the pointList in every run of the first loop (over the pointList).
Put a breackpoint in the line
pointList.remove(i);
and step through your code with the debugger and you will see it.
Instead of iterating over your list with an integer, use the for each construct supported by the Collections interface.
public void listOfExternalPoints(List<Point> list) {
for (Point pointListEntry : pointList) {
for (Point listEntry : list) {
if (pointListEntry == listEntry) {
pointList.remove(pointListEntry);
}
}
}
}
I haven't debugged this, but it looks right to me.