NextInt giving Force close - java

Whenever I try to execute this it gives me FC on my application
int a, b;
Random s = new Random();
if (diffi.contains("easy") && name.contains("sub")) {
a = s.nextInt(21);
b = s.nextInt(a);
}
But when remove "a " and put a number in its place then it starts working
int a, b;
Random s = new Random();
if (diffi.contains("easy") && name.contains("sub")) {
a = s.nextInt(21);
b = s.nextInt(21);
}
I want the second number "b" to be smaller than a in all cases

You'll get an exception if the first call to nextInt returns 0. Then the second call can't return a value which is greater than or equal to 0 but less than 0, hence the exception.
From the docs for Random.nextInt:
Throws: IllegalArgumentException - if n is not positive
You should step back for a moment though, and work out why your diagnostic approach didn't actually see those exception details. Did you check the application logs? I'd expect the exception to be clear, with the right exception, which would then make it fairly obvious what was wrong.
EDIT: I very much doubt that it's actually throwing an exception whenever that code is executed. Instead, I suspect that either that code is executing many times (so eventually you'll see that a is 0 and the exception will be thrown) or you've just been unlucky.

Related

Error array index out of bounds in some code

There is an array index out of bounds exception in my recursive function. Can someone try to point out to me why that is the case?
This line: return minChange(a, IntegerList); is having the array index out of bounds exception as well as most likely this line:
return minimumValue(1 + minChange(a - d, integerList), minChange(a, updatedList));
/* Function minChange: Minimum Change
Pseudo-code:
minChange(0, ds) = 0
minChange(a, []) = Failure
minChange(a, d :: ds) = minChange(a,ds) if d > a
minChange(a, d :: ds) = min(1 ++ minChange(a - d, d :: ds) otherwise
*/
public int minChange(int a, List<Integer> integerList) {
//int minimumResult = 0;
int indexNumber = 0;
int d = integerList.get(indexNumber); (line 246)
if(a == 0) {
// If a is 0 return 0
return 0;
} else if(integerList.isEmpty()) {
return -1;
} else if(d > a) {
integerList.remove(indexNumber); // Remove first element from list
// Recursive call to minChange
return minChange(a, integerList); (line 261)
} else {
// Create updatedList and remove first element
List<Integer> updatedList = integerList;
updatedList.remove(indexNumber);
indexNumber++;
return minimumValue(1 + minChange(a - d, integerList), minChange(a, updatedList)); (line 269)
}
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out-of-bounds for length 0
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:246)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
How can I fix this array index out of bounds exception. It seems one line needs to be fixed. If so how can I fix this error? What are some ways?
Why it Fails:
A specific sequence of events that leads to the out of bounds exception would be, for example:
minChange(1, [4]) // goes into second-to-last (else if) case, since 4 > 1. 4 is then removed.
minChange(1, []) // crashes
It's not clear what your code was intended to do in this case, since your pseudo-code doesn't define minChange(a, ds).
Even if we stipulate that the input list has to have more than one item, we'll often hit this same case:
minChange(5,[4, 8])
minChange(1,[8])
minChange(1,[])
I'm not sure what you intended to happen here, but, anyway, there are other issues...
Bugs:
There is very likely a bug in your code with this line:
// this just creates another reference to the existing list
// https://stackoverflow.com/questions/6536094/java-arraylist-copy
// meaning: both recursive calls will operate on the same list
// even though one uses the "updatedList" reference and one uses "integerList"
List<Integer> updatedList = integerList;
Also, the use of indexNumber indicates a bug, since it's only ever used when it has value 0 - the incrementing is pointless. Remember that local variables in the function are getting 'reset' in each recursive call, unless you pass them as a parameter.
Debugging Strategies:
First, clarify what you actually want the algorithm to do.
Then, check what it's actually doing. As a debugging technique, I would recommend adding some print statement at the start of the function call:
System.out.println("minChange(" + a + ", " + integerList + ")");
...so that you can see a log of what happened before the crash. You can also use a debugger for this purpose.
Finally, once it works on some simple cases, write a fuzz tester that checks your algorithm on a bunch of random lists and as of different sizes, to see if there are any cases that you missed.

The reason why IllegalArgumentException error about array length in this for loop

My program looks like this:
The input array is [1,2,3,4], the target is 7 and the output should be [2,3]
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
// nums.length-1 why is cannot be minus 1
for (int i = 0; i < nums.length-1; i++){
int result = target - nums[i];
if (map.containsKey(result)){
return new int[]{i,map.get(result)};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("No result.");
}
There will be error.
Exception in thread "main" java.lang.IllegalArgumentException: There is no two numbers in the list can add to the target.
at Solution.twoSum(Solution.java:12)
at __DriverSolution__.__helper__(__Driver__.java:8)
at __Driver__.main(__Driver__.java:54)
But change the search length by plus 1, there will succeed.
The correct code is like this
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
// the correct answer is no minus 1 in i < nums.length
for (int i = 0; i < nums.length; i++){
int result = target - nums[i];
if (map.containsKey(result)){
return new int[]{i,map.get(result)};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("No result.");
}
Can anyone help me why this happens, why could not use minus 1 here
i < nums.length
The number 12 line is
throw new IllegalArgumentException("No result.");
This is straight forward:
if (map.containsKey(result)){
return new int[]{i,map.get(result)};
will abort/break/end the enclosing method.
In other words: when a certain condition is met, the method stops within the loop.
If that condition is never met, then the loop is repeated, and then, that hardcoded, unconditional throws kicks in.
Given the edit to the question: the point here is that you wrote some pretty hard to understand code. The naming of your variables doesn't tell us anything about their intended usage.
I can only repeat what was said: this code implements some sort of algorithm. The algorithm is supposed to identify those two indexes in an input array that added together result in some "target sum". The algorithm uses a map that uses
a value from the input array as map key
the index of that value as map value
It seems that when you don't iterate to the very end of the indexes, you miss a correct condition and therefore throw.
But the real answer isn't me telling you what your code does. The real answer is that you either use a debugger to understand what your code does, or to take a piece of paper and a pen to manually run your code.
Again: this is your code, it is doing what you put into code, so you should step back and slowly, step by step dive into it to understand what exactly it is doing.

Java - Index Out Of Bounds Exception: Index: 1, Size: 2

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

Preventing vs Ignoring Errors with a Try-Catch in Java

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.

Java Recursive Method how does it work?

I'm relatively new to Java programming and I've just started learning recursion, but I can't seem to figure out how this method works in my head.
private static int mystery(int w) {
{
if (w < 0) return 0;
int x = mystery (w-2);
return w - x;
}
}
Whenever a variable like 100 is put in, it outputs 50. When 200 is input, it outputs 100. When 2 is input, it outputs 2. When 25 is input, 13 is output. I'm not sure how this method works, and I'm trying to wrap my head around it.
The way I currently view it, if you put in 100, it'll bypass the first return statement since it is greater than 0.
when it gets to the second line, it'll do 100-2, which brings in 98, then goes to the third line and does 100 - 98 = 2. Which is then returned to the original call.
I know I'm messing up on the second line of the method where the mystery (w-2) is. I assume it would bring back the result of w-2 to the beginning of the method again, and it would continue to do the method over and over again until w is smaller than 0, which should output 0 again regardless of the answer. But that's not what happens, and I don't know why.
Can anyone explain what is going on here?
What you are missing is that on the second line it doesn't just do w - 2, but calls itself with w - 2. It doesn't go further until the call returns. And the second call calls itself if w isn't < 0 and so on until you reach value lower than 0 and then return. The execution will go like this, if you visualize it:
mystery(10)
> skip first line
> x = mystery(8)
> skip first line
> x = mystery(6)
> skip first line
> x = mystery(4)
> skip first line
> x = mystery(2)
> skip first line
> x = mystery(0)
> skip first line
> x = mystery(-2)
> return 0
> return 0 - 0 (0)
> return 2 - 0 (2)
> return 4 - 2 (2)
> return 6 - 2 (4)
> return 8 - 4 (4)
> return 10 - 4 (6)
With example of w = 10. I hope you understand it better now.
private static int mystery(int w) {
{
if (w < 0) return 0;
int x = mystery (w-2);
return w - x;
}
}
Let's imagine that we call mystery(3). What happens? w<0) is false, so we don't return 0. In the next line, we call some function called mystery using the value 3-2=1 as its argument.
Despite the fact that this function we've called happens to be the same one we've just called, it's still an ordinary function call, and it returns a value. It does this by calling the function called mystery, this time using the value -1 as the argument. And this time w<0 is true, so we just return 0. Now we're back in the second call to mystery, and we've set x = 0. So that call returns w - 0 = 1. That puts us back in the first call, and now x = 1, so we return w-x = 3-1 = 2.
You might want to take a few minutes and work through this using w=4 and see what you get - this will help you understand how the recursive calls work.
After you've done this, I suggest you add a print statement or two in the function to tell you where you are and what's happening, and that'll also help - but do it on paper first.
The two given answers are excellent. Both focus on the way how to get a grasp of what recursion is. The problem with recursion is, that it is so unnatural to one who do not know what recursion is, or do not know someone who does. It's like a snake eating itself again and again.
The best way to understand recursion is to write down the calls to a recursive method, by noying the current state when it's called, and after the call write the result back. You stack up the calls and that's also the way to not used recursion at all.
So do not try too hard to understand recursion at first but first focus on the program flow. If you have seen enough recursions, it will come to you.

Categories