I am having issues with my code regarding exception in thread main. This is the error that is popping up
Exception in thread "main" java.lang.IllegalStateException: Attempt to create a stack whose capacity exceeds allowed maximum of 10000
at ResizeableArrayStack.checkCapacity(ResizeableArrayStack.java:74)
at ResizeableArrayStack.ensureCapacity(ResizeableArrayStack.java:82)
at ResizeableArrayStack.push(ResizeableArrayStack.java:28)
at ResizeableArrayStack.evaluatePostfix(ResizeableArrayStack.java:98)
at ResizeableArrayStack.main(ResizeableArrayStack.java:157)
This is my code
import java.util.*;
public class ResizeableArrayStack<T> implements StackInterface<T>
{
private T[] stack;
private int topIndex;
private boolean integrityOK = false;
private static final int DEFAULT_CAPACITY = 50;
private static final int MAX_CAPACITY = 100000;
public ResizeableArrayStack()
{
this(DEFAULT_CAPACITY);
}
public ResizeableArrayStack(int initialCapacity)
{
integrityOK = false;
checkCapacity(initialCapacity);
// The cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempStack = (T[])new Object[initialCapacity];
stack = tempStack;
topIndex = -1;
integrityOK = true;
}
public void push(T newEntry) {
checkIntegrity();
ensureCapacity();
stack[topIndex + 1] = newEntry;
topIndex++;
}
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed
maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
private void ensureCapacity() {
if (topIndex >= stack.length - 1) {
// If array is full, double its size
int newLength = 2 * stack.length;
checkCapacity(newLength);
stack = Arrays.copyOf(stack, newLength);
}
} //end ensureCapacity
public static void main(String[] args) {
String input = "ab*ca-/de*+";
ResizeableArrayStack<String> astack = new ResizeableArrayStack<>(input.length());
int evaluation = astack.evaluatePostfix(input);
System.out.println("Evaluating Postfix Expressions");
System.out.println("The evaluation of the postfix expression is " + evaluation);
}
}
I'm pretty sure the issue is with how the capacity values are set and compared but I can't figure out why I am getting this error. I think the issues are within the constructors that involve capacity and main method. Please ignore the evaluatePostfix method in the main as the errors all say they come from the constructors and main. I can put the evaluatePostfix up if you think the problem is within it. I also deleted the methods that weren't brought up in the problem.
The code you posted is not a MCVE. It doesn't compile because it is missing methods including checkIntegrity and evaluatePostfix. Even after I work around the missing methods, the code you posted does not cause IllegalStateException to be thrown. At a guess, after looking through the code that you did post, as well as the stack trace, the culprit appears to be method ensureCapacity which contains the following line:
int newLength = 2 * stack.length;
The value assigned to newLength may be greater than MAX_CAPACITY.
After you assign a value to newLength, you call method checkCapacity which explicitly throws a IllegalStateException.
private void checkCapacity(int capacity) {
if (capacity > MAX_CAPACITY) {
throw new IllegalStateException("Attempt to create a stack whose capacity exceeds allowed maximum of " + MAX_CAPACITY);
}
} // end checkCapacity
But as I wrote earlier, in the code that you posted capacity is never greater than MAX_CAPACITY and hence the code in your question never throws IllegalStateException.
I recommend that you run your code through a debugger. If you are using an IDE, then it should give you the option of running your code in "debug" mode. If you don't know how to use the debugger of the IDE then you should learn because knowing how to debug code is an essential skill for a programmer and a debugger helps a lot when it comes to debugging your code.
Related
I'm quite new to java. So I've got some code that is supposed to add files to a stack and compare the stack contents with an existing reference. Here's the class that should create the stack:
public class ArrayStack<T> implements ArrayStackADT<T> {
private T[] stack;
private int top;
// constructor, passes default capacity
public ArrayStack() {
top = -1;
stack = (T[]) new Object[14];
}
// constructor, initializes capacity to stack and top
public ArrayStack(int initialCapacity) {
top = -1;
stack = (T[])new Object[initialCapacity];
}
}
and here is the code that calls the stack:
public static void main(String[] args){
StartSearch path = new StartSearch(args[0]);
int distance = Integer.parseInt(args[1]);
ArrayStack stack = new ArrayStack(); // creates empty stack
MapCell cell = path.targetMap.getStart(); // gets starting cell
stack.push(cell); // pushes starting cell to stack
}
Not sure if I showed enough code, so please let me know if I didn't. I had some push and pop methods to insert and remove stack items, and for each push/pop they'd print "push" + the value:
if (dataItem instanceof MapCell) {
sequence += "push" + ((MapCell)dataItem).getIdentifier();
}
else {
sequence += "push" + dataItem.toString();
}
For some reason though, when I go to print sequence later, it outputs this:
nullpush0push2push3
Instead of what I need it to output:
push0push2push3
Do empty stacks automatically have a null value or something? how do I get rid of the null value at the beginning?
It hasn’t got anything to do with your stack class. It’s how you initialize your String variable. Or perhaps forgot to initialize it? To demonstrate:
String sequence = null;
sequence += "push1";
System.out.println(sequence);
Output is:
nullpush1
Instead initialize sequence to the empty string:
String sequence = "";
push1
Or use a StringBuffer or StringBuilder:
StringBuilder sequence = new StringBuilder();
sequence.append("push1");
System.out.println(sequence);
Output is identical:
push1
I have a class X that saves ints in an array:
public class X{
public int[] a;
public boolean[] allocated;
//constructor
public X(int len){
this.a = new a[len];
this.a = new allocated[len];
}
public void save(int tosave) throws ArrayStoreException{
int pos = 0;
for(int i=0; i<allocated.length; i++){
if(allocated[i] == true){
pos++;
}
}
if(pos == allocated.length){
throw new ArrayStoreExeption("no free space left");
}
a[pos] = tosave;
allocated[pos] = true;
}
}
And the class Y with save2 that I still need to implement...
public class Y extends X{
public void save2(int tosave){
// to be implemented
}
}
For save2 I want it to do the same as save with the exception, that if there is no more free space left or the ArrayStoreException occurs then I want the array to be doubled the size and then the parameter inserted to the array.
So if I do:
try{
super.save(tosave); // If no exception is thrown, does it save 'tosave'?
}catch(ArrayStoreExeption e){
System.out.println("noe free sapce left");
}
My first question is: if the try block does not trigger an exeption, will the code after catch block execute?
I don't know where to put the piece of code savely which doubles the array size if there is no more space left or the exeption is thrown.
Can someone help?
EDIT:
Can I place the code, that double the array inside the catch block?
the code you have posted has a number of syntax errors. I suggest you get those fixed and repost if this answer doesn't satisfy you.
yes you can implement your code to expand the array inside the catch block of the subclass. It will need to call the superclass's save method
your subclass should probably override the save method rather than create a new save2 method
using a boolean array doesn't make a lot of sense. Given you are not leaving any gaps wouldn't it be easier just to keep a single index of the first unallocated spot?
wherever possible keep your member variables private or protected. In this case if the subclass is going to expand the array then it will likely need to be protected. Better would be to make it private and have a protected method in the superclass to expand it.
Arrays.copyOf will do the expansion for you
So putting all that together:
class Fixed {
private int size;
private int[] store;
private int index = 0;
public Fixed(int size) {
this.size = size;
store = new int[size];
}
public void save(int value) throws ArrayStoreException {
if (index == size)
throw new ArrayStoreException();
store[index++] = value;
}
protected void expand() {
size *= 2;
store = Arrays.copyOf(store, size);
}
}
class Expandable extends Fixed {
public void save(int value) {
try {
super.save(value);
} catch (ArrayStoreException x) {
expand();
save(value);
}
}
}
If you prefer to avoid the recursion then you could use:
public void save(int value) {
try {
super.save(value);
} catch (ArrayStoreException x) {
expand();
try {
super.save(value);
} catch (ArrayStoreException x) {
throw new IllegalStateException("Cannot save after expansion");
}
}
}
You can put the code in finally block.
Regardless there is an exception or not, finally block do execute. (Exception : if called System.exit(0); in the try block.)
Conceptually, let's begin with
Try Block - You put the code here where you think there may be an ArrayStoreException.
Catch Block - This Block runs only if there is any exception thrown from try block.
You put the code, how it should handle. As per requirement, you can throw a message to console telling about the details of error, as in your case ArrayStoreException message and can prompt the user that you are going to double the capacity of ArrayList and can hence write the code for increasing the size of ArrayList
Finally Block - This block runs regardless of any exception is thrown or not. You can write the code for increasing the size of ArrayList here also. But, it will run even if there is no ArrayStoreException and the ArrayList has the capacity.
Note : If there is an exception thrown by the code, and is not handled or declared, so the code will stop running and no further code will run. But, if there is a proper handling of errors, the rest of the code runs.
For your case, I will suggest definitely to leverage the use of try-catch-finally block and put the code for doubling the size in catch block.
I am trying the following code for heap sort which is giving ArrayIndexOutOfBoundsException exception:
package com.Sorting;
import java.util.Arrays;
public class HeapSort {
private static int arr[];
private static int l,r,max,hsize;
/**
* #param args
*/
public static void main(String[] args) {
int []numbers={55,2,93,1,23,10,66,12,7,54,3};
System.out.println(Arrays.toString(numbers));
HeapSort(numbers);
System.out.println(Arrays.toString(numbers));
}
private static void HeapSort(int myarr[]) {
// TODO Auto-generated method stub
arr = myarr;
hsize = arr.length - 1;
BuildHeap(arr);
for(int i = hsize;i>0;i--)
{
swap(0,i);
hsize--;
SatisfyHeap(arr,0);
}
}
private static void BuildHeap(int[] arr) {
// TODO Auto-generated method stub
for(int i = hsize/2; i>=0;i--)
{
SatisfyHeap(arr, i);
}
}
private static void SatisfyHeap(int[] arr, int i) {
// TODO Auto-generated method stub
l = 2*i;
r = 2*i+1;
if(l<=hsize && arr[l]>arr[i])
// if(arr[l]>arr[i] && l<=hsize )
{
max = l;
}
else
max = i;
if(r<=hsize && arr[r]>arr[max])
{
max = r;
}
if(max!=i)
{
swap(i,max);
SatisfyHeap(arr, max);
}
}
private static void swap(int i, int max) {
// TODO Auto-generated method stub
int temp = arr[i];
arr[i] = arr[max];
arr[max] = temp;
}
}
The above code does not give any error if I just swap the expressions used on the left hand side and right hand side in the if statement of SatisfyHeap method. i.e. you can try commenting the third line of the SatisfyHeap method and uncomment the fourth line. Please help to understand this magic.
Short answer
The magic is called "short-circuit evaluation" and it was designed speciifcally for the cases like this.
Longer answer
In Java and many other languages logicallly code
if (condition1 && condition2) {
do something
}
is equivalent to
if (condition1) {
if (condition2) {
do something
}
}
By "equivalent" here I mean that if condition2 is something to be computed it will not be computed if condition1 happens to be false. Also this is correct from the boolean logic point of view. This trick is useful in two respects. First, it improves performance by skipping evaluation calculation2. Secondly, it is useful in cases such as yours were condition1 is a "guard condition" for condition2.
Another example is function isEmptyString that is implemented by many Java-developers in a following way
public static boolean isEmptyString(String s) {
return (string == null) || (string.length() == 0);
}
Without short-circuting logic, this expression would raise a NullPointerException if s happens to be null.
Your specific case (Why ArrayIndexOutOfBoundsException at all?)
Another point of your question might be "How it happens that there is ArrayIndexOutOfBoundsException at all?". To answer this question consider the case when the very first element is actually the largest in the heap and we should move it down to the last layer of the tree. This movement down is implemented by your SatisfyHeap. So now assume that we did last swap that moved the biggest element to the bottom. Now as max was changed we'll do one more recursive call and in that call i > arr.length / 2 so l = 2*i > arr.length and thus the exception happens.
Side-note, I'd say that unless you pre-allocate arr to be bigger than actual heap size storing hsize independently from arr.length is a bad idea that makes code harder to understand.
Following gives you an error
if(arr[l]>arr[i] && l<=hsize )
because l is greater than the size of the array and you are trying to get the array element by passing l which is out of array's bounds.
Following works for you
if(l<=hsize && arr[l]>arr[i])
because in the if condition, the first thing that is evaluated is the expression l<=hsize. Since l is greater than hsize, the expression evaluates to false. Since the two clauses of your if predicate are joined with an && operator, as per the short circuiting rules, the expression in the second clause is not even evaluated saving you from accessing the array with an out of bound index. Therefore you don't get any error.
I need to write a parent Java class that classes using recursion can extend. The parent class will be be able to realize whenever the call stack changes ( you enter a method, temporarily leave it to go to another method call, or you are are finsihed with the method ) and then print it out. I want it to print on the console, but clear the console as well every time so it shows the stack horizantaly so you can see the height of each stack to see what popped off and what popped on... Also print out if a baseline was reached for recursive functions.
First. How can I using the StackTraceElements and Thread classes to detect automatically whenever the stack has popped or pushed an element on without calling it manually?
Second, how would I do the clearing thing?
For instance , if I had the code:
public class recursion(int i)
{
private static void recursion(int i)
{
if(i < 10)
System.out.println('A');
else
{
recursion(i / 10 );
System.out.println('B');
}
}
public static void main(String[] argv)
{
recursion(102);
}
}
It would need to print out the stack when entering main(), when entering recursion(102) from main(), when it enters recursion(102 / 10), which is recursion(10), from recursion(102), when it enters recursion(10 / 10), which is recursion(1) from recursion(10). Print out a message out when it reaches the baseline recursion(1).. then print out the stacks of reversed revisitation of function recursion(10), recursion(102) and main(). finally print out we are exiting main().
Thread class allows managing OS threads, it does not have anything to do with the call-stack. StackTraceElement represents a stack-frame but you need a StackTrace to get to it.
You are looking for a notification for when the stack-trace changes, for example a frame is added (a method is entered) or removed (a method is exited).
By far the most appropriate tool for this task is AspectJ. It lets you define advices (a kind of method) that gets called (besides other cases) when other methods are entered or existed. These triggers that result in the advices getting called are called pointcuts -- they can be method entry, exit and the methods can be described using wildcards: the pointcut MyClass.get* applies to all get methods of MyClass.
I started to write my own before seeing your answer. It is simplistic in form but the shell is:
package stackTraceLogger;
import java.util.ArrayList;
public class StackTraceLogger
{
static final int MAX_ROW = Integer.MAX_VALUE;
static final int MAX_COLUMN = Integer.MAX_VALUE;
static public ArrayList<ArrayList<String>> stringTrace;
//private ArrayList<ArrayList<StackTraceElement>> stack;
public StackTraceLogger()
{
stringTrace = new ArrayList< ArrayList <String>>();
//stack = new ArrayList<ArrayList<StackTraceElement>>();
}
static public void addStack(StackTraceElement[] inputTrace)
{
int size = inputTrace.length;
// make an ArrayList with the strings of all the StrackTraceElements
ArrayList<String> str = new ArrayList<>(size);
for(int i = 0; i < size; i++)
{
str.add(i,inputTrace[i].getMethodName());
}
// Add the ArrayList to the 2D ArrayList of the stacks
}
static public void printTrace()
{
/* if(stringTrace.get(0).size() > 0)
{
for(int i = 0; i < stringTrace.size(); i++)
{
System.out.println(stringTrace.get(i));
for(int j = 0; j < stringTrace.get(j).size(); j++)
System.out.println(stringTrace.get(i).get(j));
}
}*/
}
static private ArrayList<String> convertToArrayList(StackTraceElement[] inputTrace)
{
ArrayList<String> strTrace = new ArrayList<>();
for(int j = 0; j < inputTrace.length; j++ )
strTrace.add(inputTrace[j].getMethodName());
return strTrace;
}
}
I am getting the following error:
Exception in thread "main" java.lang.NullPointerException
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
Line 19 contains:
dramaticGame1.ejectBall();
the Dramatic Game class contains the following:
public class DramaticMachine extends Machine
{
// Constructor is given the person's name.
public DramaticMachine(String name, int length)
{
super(name, length);
}
public Ball ejectBall()
{
if (getNoOfBalls() >= 0)
return null;
else
{
//Math.random() * getNoOfBalls yields a number
//which is >=0 and < number of balls.
int ejectedBallIndex = (int) (Math.random() * getNoOfBalls());
for (int selectedBallIndex = 0; selectedBallIndex < ejectedBallIndex; selectedBallIndex++)
{
Ball selectedBall = getBall(selectedBallIndex);
selectedBall.flash(4, 5);
}
Ball ejectedBall = getBall(ejectedBallIndex);
ejectedBall.flash(4, 5);
swapBalls(ejectedBallIndex, getNoOfBalls() -1);
removeBall();
return ejectedBall;
}//else
}//ejectBall
public String getType()
{
return "Dramatic Lottery Machine";
}//getType
}//dramaticMachine
How can i fix this?
This is the code for the DramaticGame class:
public class DramaticGame extends Game
{
// Constructor is given the person's name.
public DramaticGame(String machineName, int machineSize, String rackName, int
rackSize)
{
super(machineName,machineSize,rackName,rackSize);
}
public Machine makeMachine(String machineName, int machineSize)
{
return new DramaticMachine(machineName, machineSize);
}//makeMachine
}
This is the code for LotteryTestB:
public class LotteryTestB
{
public static void main (String args[])
{
SpeedController speedController
= new SpeedController(SpeedController.HALF_SPEED);
LotteryGUI gui = new LotteryGUI("TV Studio", speedController);
Worker worker = new TraineeWorker("Jim",0);
DramaticGame dramaticGame1 = new DramaticGame("Lott O'Luck Larry", 49,
"Slippery's Mile", 7);
gui.addGame(dramaticGame1);
worker.fillMachine(dramaticGame1);
for (int count = 1; count <=dramaticGame1.getRackSize(); count++)
{
dramaticGame1.ejectBall();
speedController.delay(40);
}//for
}//main
}//LotteryTestB
NullPointerException is one of the easier problems to chase down. It means that some reference wasn't initialized properly. It should be easy to figure out by stepping through your code with a debugger.
If you are incapable of using a debugger, the stack trace makes this easy for you. There are only four places to look, and it says exactly where they are.
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
It's not the bottom one. The reference to dramaticGame is the only one on that line, and you call new to initialize it. Go on to the next one. Add a log or print statement to prove where the null reference is, then go and initialize it properly.
I don't think your code is layered properly. You'll never get this working unless you can decompose the problem into smaller chunks, unit test them until they work, and then use that code to build up the complex solution.
Separate UI from the game itself. Get the game working, then worry about display issues.