This question already has an answer here:
NullPointerException Error with JPanel and CardLayout
(1 answer)
Closed 8 years ago.
So I'm getting this nullpointerexception. I know the line it's being caused at, I just am having trouble seeing what's causing it in my code.
import java.util.*;
public class NoDuplicatesQueueWilson<T> implements NoDuplicatesQueueInterfaceWilson<T>
{
private int MAX_QUEUE = 5; // Default array size, small for testing purposes
private T[] items; // The array of the queue.
private int front; // The first entered item of a queue.
private int back; // The last entered item of a queue.
private int count; // A counter.
public NoDuplicatesQueueWilson() // Default constructor
{
T [] items = (T[]) new Object[MAX_QUEUE];
front = 0;
back = MAX_QUEUE-1;
count = 0;
}
// Begin Queue Operations
// isEmpty() checks the array to determine if there is an items in it.
public boolean isEmpty()
{
return count == 0;
}
// isFull() checks to see if the array is full or not.
public boolean isFull()
{
return count == MAX_QUEUE;
}
// enqueue(Object newItem) adds items to the back of the queue if it is not full.
// If it is full, it will double the size of the array of items,
// and re-create the array, adding the item onto the new array.
public void enqueue(T newItem) {
if(!isFull())
{
back = (back+1) % (MAX_QUEUE);
items[back] = newItem;
++count;
}
else
{
MAX_QUEUE = MAX_QUEUE * 2;
System.out.println("The array was full. We've doubled the size.");
T [] items = (T[]) new Object[MAX_QUEUE];
back = (back+1) % (MAX_QUEUE);
items[back] = newItem;
++count;
} // End if
} // End Enqueue
When I run it in my driver program (with test data), the exception occurs at line 43 of the given code (my main class containing the methods and constructors), which is in the middle of my enqueue method. Specifically this line:
items[back] = newItem;
Any suggestions on what I might need to do or be looking for to see where my mistake was?
In constructor you are not initializing T [] items but you are creating new local variable. It should be
public NoDuplicatesQueueWilson() // Default constructor
{
items = (T[]) new Object[MAX_QUEUE]; // notice the difference
front = 0;
back = MAX_QUEUE-1;
count = 0;
}
Edit: Also please check else part of code in enqueue method.
In your constructor, this line assigns to a local variable, instead of an instance variable:
T [] items = (T[]) new Object[MAX_QUEUE];
You can access the instance variable items with this.items:
this.items = (T[]) new Object[MAX_QUEUE];
You could also just use items = ... as there is no ambiguity in this case.
The same bug is also in your enqueue(T newItem) method at T [] items = ....
Related
I have an assignment to push Strings into a stack. I created a program that will store numbers but I cannot figure out the correct way to define the array to take a string. Here is my code. My Java is rusty so I am trying to remember all this from my first java class 2 years ago. I am sure it is super simple but I cannot find anything online where strings are stored in a stack for me to see how to do it. Thanks for the help!
public class stackx {
private int maxSize; //number of items in stack
private int[] stackArray;
private int top; // top of stack
public stackx(int arraySize) {
maxSize = arraySize;
stackArray = new int[maxSize];
top = -1;
}
public void push(int a) { //put value on top of stack
if (top == maxSize - 1)
{
System.out.println("Stack is full");
} else {
top = top + 1;
stackArray[top] = a;
}
}
public int pop() { //take item from top of stack
if (!isEmpty())
return stackArray[top--]; // access item, decrement top
else {
System.out.println("Stack is Empty");
}
}
public int peek() //peek at the top of the stack
{
return stackArray[top];
}
public boolean isEmpty() { //true if stack is empty
return top == -1;
}
public void display() {
for (int i = 0; i <= top; i++) {
System.out.print(stackArray[i] + " ");
}
System.out.println();
}
} // End class stackx
**Driver class Here**
public class practicestack {
public static void main(String[] args) {
stackx newStack = new stackx(5);
newStack.push(redShirt);
newStack.push(greenShirt);
newStack.push(yellowPants);
newStack.push(purpleSocks);
newStack.push(pinkSocks);
stackx.peek();
//Display the Full Stack
newStack.display();
//Test removing a value using pop method
newStack.pop();
newStack.display();
}
}
This should be easy, I will provide you a small hint, if you still can't figure it out, I will post entire code
when you declare something like this
private int[] stackArray;
and use this array to push and pop your items, as this is Integer array you can only use this implementation for Integers.
Now your requirement is to push and pop Strings, so essentially you should do something like this.
private String[] stackArray;
Note : Your Push and pop method will change likewise, those will be small changes
Hope this helps!
Good luck.
Your stack only takes ints. You need it to take Objects if you want to store anything at all. Java doesn't let you manipulate pointers, so you can't just use int like in C/C++. You could also use generics, e.g. public class stackx<T>, which would give you something like stackx<String> newStack = new stackx<>(5);.
Just modify int to String.Here is the Demo.
Debugging on some solutions for this problem, and for the following code snippet, I think the logic is wrong in method pop(), since when executing "indexUsed--", spaces are removed continuously, but when deleting elements, it is not necessarily to be continuous.
Please feel free to correct me if I am wrong.
int stackSize = 300;
int indexUsed = 0;
int[] stackPointer = { -1, -1, -1 };
StackNode[] buffer = new StackNode[stackSize * 3];
void push(int stackNum, int value) {
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = indexUsed;
indexUsed++;
buffer[stackPointer[stackNum]] = new StackNode(lastIndex, value);
}
int pop(int stackNum) {
int value = buffer[stackPointer[stackNum]].value;
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = buffer[stackPointer[stackNum]].previous;
buffer[lastIndex] = null;
indexUsed--;
return value;
}
int peek(int stack) { return buffer[stackPointer[stack]].value; }
boolean isEmpty(int stackNum) { return stackPointer[stackNum] == -1; }
class StackNode {
public int previous;
public int value;
public StackNode(int p, int v) {
value = v;
previous = p;
}
}
You are right, this approach is not only ridiculously inefficient and overcomplicated, but also incorrect.
Here is the simple test to prove:
StackArray stack = new StackArray();
stack.push(0, 0);
stack.push(1, 10);
System.out.println(stack.pop(0));
stack.push(1, 20);
System.out.println(stack.pop(1));
System.out.println(stack.pop(1));
Produces:
Exception in thread "main" java.lang.NullPointerException
at StackArray.pop(StackArray.java:18)
Stack data structure is usually implemented as array or single-linked list. Linked list is less efficient, because its elements are scattered across the heap, also its elements have memory overhead (node object with pointers). Array, on the other hand, is faster, but it has fixed size, so it can't be used for all tasks.
Each of these approaches has its pros and cons, but there is absolutely no point in creating mixed approach that has only disadvantages of both approaches (has fixed capacity and memory overhead).
If this is a synthetic task with the restriction of using only one array to store elements of all three stacks, then following approach can be used.
Logically split elements of array in pairs. Each pair will represent one node of single-linked list. First element of the pair will hold the value, while second element will be the pointer to the next node.
It's clear that array can hold any number of independent single-linked lists (as long as it has sufficient capacity) and you know the indices of the heads.
The idea is similar to the approach given in description, to hold the pointers to the heads of three lists, but (!) in addition hold the pointer to the list that represent "free memory" and includes all non-occupied elements of the array. Initially this "heap" list will contain all elements of the array. When you push element into one of the stacks, you need to pop element from the heap and use it to create element of the desired stack. When element is popped from the stack, this element is pushed back to heap.
You can start one of the stacks from one end of the array. You can start the other stack from the other end of the array. You can put the third stack in the middle. When, one of the side stacks need space, you need to shift the middle stack. However, I have another implementation by help of free list. You can try this implementation also:
public class ThreeStacksWithOneArray {
//This is the stack node class
class StackNode {
//This is the value of the node
int value;
//This is showing the previous node
int prev;
//This is the constructor of the class
StackNode(int value, int prev) {
this.value = value;
this.prev = prev;
}
}
//This keeps the stack nodes
private StackNode[] stackNodes = null;
private static int CAPACITY = 10;
//This keeps the top of free list
private int freeListTop = 0;
//This is the variable for the size
private int size = 0;
//These are the pointers to the three stacks
private int[] stackPointers = { -1, -1, -1 };
//This is the constructor of the main class
ThreeStacksWithOneArray() {
//Initialize the stack nodes
stackNodes = new StackNode[CAPACITY];
//initialize the free list
initFreeList();
}
//Initialize the free list
private void initFreeList() {
for (int i = 0; i < CAPACITY; i++) {
//The value of each node is 0 and it points to the next node
stackNodes[i] = new StackNode(0, i + 1);
}
}
//This is the push procedure
public void push(int stackNum, int value) throws Exception {
//Print the push information
System.out.println("Push to stack "+stackNum+" value "+value);
int freeIndex;
int currentStackTop = stackPointers[stackNum - 1];
//Find the free node
freeIndex = getFreeNodeIndex();
//Make a new node in the free index
StackNode n = stackNodes[freeIndex];
//Setting the previous node
n.prev = currentStackTop;
//Setting the value
n.value = value;
stackPointers[stackNum - 1] = freeIndex;
}
//This is the pop method
public StackNode pop(int stackNum) throws Exception {
//From which stack you want to pop. -1, since it starts from 0
int currentStackTop = stackPointers[stackNum - 1];
//This checks for stack underflow
if (currentStackTop == -1) {
throw new Exception("UNDERFLOW");
}
//Get the node as a temp node
StackNode temp = stackNodes[currentStackTop];
//Remove the node from stack
stackPointers[stackNum - 1] = temp.prev;
//Put this node as free node
freeStackNode(currentStackTop);
//Print the pop information
System.out.println("Pop from stack "+stackNum+" value: "+temp.value);
//Return the value
return temp;
}
//Get a free node index
private int getFreeNodeIndex() throws Exception {
int temp = freeListTop;
//Overflow
if (size >= CAPACITY)
throw new Exception("OVERFLOW");
freeListTop = stackNodes[temp].prev;
size++;
//return the free node index
return temp;
}
//Make one index free after a pop
private void freeStackNode(int index) {
stackNodes[index].prev = freeListTop;
//Put the index in free list
freeListTop = index;
//Decrease the size by one
size--;
}
public static void main(String args[]) {
// Test Driver
ThreeStacksWithOneArray mulStack = new ThreeStacksWithOneArray();
try {
//Adding to those three stacks
mulStack.push(1, 11);
mulStack.push(1, 12);
mulStack.push(1, 13);
mulStack.push(1, 14);
mulStack.push(2, 21);
mulStack.push(2, 22);
mulStack.push(3, 31);
mulStack.push(3, 32);
//Popping from those three stacks
mulStack.pop(1);
mulStack.pop(2);
mulStack.pop(3);
} catch (Exception e) {
e.printStackTrace();
}
}
}
For more information, visit this: https://github.com/m-vahidalizadeh/foundations/blob/master/src/data_structures/ThreeStacksWithOneArray.java. I hope it helps.
I am getting the error now that BookCollection.java:67: error: incompatible types
collection[lastElement++] = b;
Also am not sure if my constructor is set up correctly? The directions were:
Constructor:
Given a parameter specifying the limit on the collection size, an empty book collection is created using the given parameter. The parameter should not exceed the preset maximum size 200.
Am I initializing my variables correctly then? An answer below helped me change my code, but although I do not get errors within my constructor, I feel as though it may not be correct according to the directions....
I'll paste the couple chunks of my code that pertain to the question.
public class BookCollection{
//data fields, need complete
private int limit = 200;
//Array of type book
private int Book[];
//actual size of collection, initialized to zero. Must never exceed limit
private int collection[];
private int lastElement;
//Constructor
public BookCollection(int l, int c[], int le,int b[]){
Book = b;
collection = c;
limit = l;
lastElement = le;
int lastElement = 0;
if(limit <= 200){
Book[] collection = new Book[limit];
} else{
throw new UnsupportedOperationException("CannotExceedLimit");
}
}
ANNDDDD where I am getting the error:
public void addBook(int b[], int c[]) {
Book = b;
collection = c;
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You have not declared i as an integer in your for loop. So add the declaration with initialization. Replace this
for(i=0; i<collection.length; i++){
with
for(int i=0; i<collection.length; i++){
This statement
BookCollection[] collection = new BookCollection[limit]; //initialize array of 200
declares a local array. It gets destroyed as soon as you leave the constructor.
The collection that stays around is this one:
private int collection[];
It consists of ints, so when you try to do this
collection[i].add(b);
the compiler correctly complains that int does not have a method called add.
Good chances are, even declaring the collection as
private Book[] collection;
and initializing it in the constructor as
collection = new Book[limit];
is not going to help, though: unlike collections, Java arrays do not let you change their size dynamically, so you need to store an index of the last element of the collection[] array that has been set.
This leads to understanding that you need a loop for finding duplicates, and noting else: define an element int lastElement, set it to zero in the constructor, and rewrite the addBook method as follows:
public void addBook(Book b) {
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You did't declared i as a int type variable, make it as
for(int i=0; i<collection.length; i++){
^here
//...
}
I know this question has asked many times but after seaching for an hour i still have problem.
I want to use a lifo stack which has a max number of elements it can store.After it reach the max number is deletes the element at first place and replace it with the new so in first pop i can get this element and in second i have to get the element at size-1.
What i tried:
1) Using a modified Stack ,as described here .The problem is that it always returning the first 5 elements(if the size is 5) i added.
class StackSizable<E> extends Stack<E>{
int maxSize;
StackSizable(int size)
{
super();
this.maxSize=size;
}
#Override
public E push(E elt) {
super.push(elt);
while (this.size() > this.maxSize) {
this.removeElementAt(this.size() - 1);
}
return null;
}
}
2)Using an ArrayDeque ,i dont see any diference from a simple Stack , its not setting any limit(am i using it wrong?)
ArrayDeque<State> lifo = new ArrayDeque<State>(5);
lifo.pop();
lifo.push(state);
I want to use this in a puzzle game for undo-redo functionality
Solved: I ended using a fixed size stack as tom said ,mainly for the performance
public class FixedStack<T> {
private T[] stack;
private int size;
private int top;
private int popBalance = 0;//its used to see if all the elements have been popped
public FixedStack(T[] stack) {
this.stack = stack;
this.top = 0;
this.size = stack.length;
}
public void push(T obj) {
if (top == stack.length)top = 0;
stack[top] = obj;
top++;
if (popBalance < size - 1)popBalance++;
}
public T pop() {
if (top - 1 < 0)top = size;
top--;
T ob = stack[top];
popBalance--;
return ob;
}
public void clear() {
top = 0;
}
public int size() {
return size;
}
public boolean poppedAll() {
if (popBalance == -1)return true;
return false;
}
}
I think the most efficient way to this is with a fixed array, with size equal to your max # of elements, and an index that points to the element that is currently the 'top' of the queue.
When you add a new element you add it at index+1 (wrapping back to element 0 if necessary) and possibly overwriting an element that no longer fits. When you pop an element you do the reverse.
This way your data structure never has to be re-ordered, and you can use an array which is more light-weight then a collection.
When the maximum size has been reached, your line
this.removeElementAt(this.size() - 1);
then immediately removes the last pushed element (which you just pushed), which is the top of the stack. You need to remove the first element instead (bottom of the stack):
this.removeElementAt(0);
I've been working for a couple of hours now trying to get an Stack based on an Array built and implemented. I have checked several sources and it looks like my ArrayStack class is constructed properly. However, when I run debug, 'head' stays null and size & sp go back to 0: therefore, nothing is actually getting pushed on the stack. Can someone help me understand what I have implemented incorrectly?
Here is my ArrayStack class:
public class ArrayStack <T>{
protected int sp; //empty stack
protected T[] head; //array
private int size;
#SuppressWarnings("unchecked")
public void stack(T t){
sp = -1;
size = 24; //sets the default size of the stack
head = (T[]) new Object [size];
}
public boolean isFull(){
return sp == -1;
}
public void push (T t){
if (!isFull())
head[++sp] = t;
}
public T pop (){
if (isFull()){
return null;
}
else
return head[sp--]; //LINE 30
}
}
Here is my Main Method:
public class StacksAndQsMain {
public static void main(String[] args) {
//Array Implementation
ArrayStack<String> as = new ArrayStack<String>();
String s = "Hello";
String s1 = "World";
String s2 = "Again";
as.push(s);
as.push(s1);
as.push(s2);
System.out.println (as.pop()); //LINE 15
System.out.println();
System.out.println (as.pop());
System.out.println();
System.out.println (as.pop());
System.out.println();
}
}
Lastly, here is my stack trace:
Exception in thread "main" java.lang.NullPointerException
at stackAndQs.ArrayStack.pop(ArrayStack.java:30)
at stackAndQs.StacksAndQsMain.main(StacksAndQsMain.java:15)
My variables at public void push (T t)
this ArrayStack<T> (id=17)
head null
size 0
sp 0
t "Hello" (id=18)
You are using the default constructor for the class, which will initialize all of the data members to their default values:
public class ArrayStack <T>{
protected int sp; //empty stack <-- initialized to 0
protected T[] head; //array <-- initialized to null
private int size; // <-- initialized to 0
// ... snip
}
You need to implement the default constructor to initialize this object state to the defaults you want (in the stack() method). When you call push, the isFull method will return false (as the default integer value of 0 != -1).
Instead of implementing a default constructor, you could just call stack() before using it, but there's no reason to let your object be constructed in a booby-trapped state!
Additionally, your isFull method should be checking sp against the size variable, right now it is behaving as an isEmpty check :-)
I noticed two things.
First as others have mentioned you needed to create a constructor and initialize the array. Second, the isFull method should check that sp != this.size -1, basically making sure your not at the 24 element limit of your stack implementation. After changing, isFull you should negate the if conditional in the push method to check that the stack is not full. Also, I would remove the check on the pop method to check if the stack isFull, why prevent someone from popping an element just because the stack is full? Instead check that the stack is not empty.
public class ArrayStack<T> {
protected int sp; // empty stack
protected T[] head; // array
private int size;
#SuppressWarnings("unchecked")
public ArrayStack() {
sp = -1;
size = 24; // sets the default size of the stack
head = (T[]) new Object[size];
}
public boolean isFull() {
return sp == this.size -1;
}
public boolean isEmpty() {
return sp == -1;
}
public void push(T t) {
if (!isFull())
head[++sp] = t;
}
public T pop() {
if (isEmpty()) {
return null;
} else
return head[sp--]; // LINE 30
}
public static void main(String[] args) {
// Array Implementation
ArrayStack<String> as = new ArrayStack<String>();
String s = "Hello";
String s1 = "World";
String s2 = "Again";
as.push(s);
as.push(s1);
as.push(s2);
System.out.println(as.pop()); // LINE 15
System.out.println();
System.out.println(as.pop());
System.out.println();
System.out.println(as.pop());
System.out.println();
}
}
You're not using any selfdefined constructor. You're using the default one which causes your sp variable to be '0' instead of '-1'. This results in an sp value of 3 after your pushing, but sp[3] has no data in it which results in a NPE when you're trying to pop it.
Change your stack method to
public ArrayStack(T t){
sp = -1;
size = 24; //sets the default size of the stack
head = (T[]) new Object [size];
}
to make it a selfdefined constructor.
After you push "Hello" (1st object) sp becomes 0 and head[0] is assigned. From this moment all further "pushes" will produce nothing since your IsFull is still testing (sp == -1).