So my friend created a queue class which has an instance variable size = 0; and for the add method he uses.
But what will happen to index 0 in this case?
It will not have an elements declared to it since add starts from size++. Which is 1 starting position.
public void add(T data) {
if(size > elements.length) {
throw new QueueException("Queue is full");
}
elements[size++] = data;
}
size++ returns the size value before it gets incremented in the background. Because of that the elements[0] will be assigned. See Oracle Tutorial on incrementing.
The problem is with the last element. The code will attempt to assign elements[elements.length] which is above the array capacity. The guard should be:
if (size >= elements.length) {
throw new QueueException("Queue is full");
}
Related
I'm trying to implement Queues in JAVA. I'm a beginner. I dont understand why this isn't working. Push() works fine but pop() isn't working. Can someone please point out where im going wrong?
pop():
public void pop()
{
for(int i=0;i<length;i++)
{
while(i<(length-1))
{
arr[i]=arr[i+1];
}
}
}
push():
public void push(int x)
{
push:for(int i=0;i<length;i++)
{
if(arr[i]==null)
{
arr[i]=x;
break push;
}
}
}
show():
public void show()
{
int c=0;
for(int i=0;i<length;i++)
//if(arr[i]!=null)
{
System.out.println(arr[i]);
c++;
}
System.out.println("Current Capacity "+c+"/"+length);
}
main()
public static void main(String...i)
{
System.out.println("Stack Implementation");
Queue stack = new Queue();
System.out.println("Push");
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.show();
System.out.println("Pop");
stack.pop();
stack.show();
}
The output doesn't show any data after pop() is run.
You don't increment i in pop() so the while loop will run endlessly.
In push you are using a for loop which increments i: :for(int i=0;i<length;i++ /*here*/)
You also don't initialize i in pop() so it will probably have the value of the last increment in push(). That value will be the index of the next empty element (if there's one left) and thus that's wrong anyways. However, you want to pop from the front, so you'd need to start at i = 0 - in that case another for loop would work as well, i.e. you just copy the value of element at i+1 to the index i and set the last element to null (for more efficiency you could stop once i+1 has a null element).
Edit: now that you've posted more code for pop() the situation is a little different. You are already using a for loop in pop() but another loop inside that. I assume you want to do if(i<(length-1)) instead of while(i<(length-1)) - but in that case you'd still have to handle the last element, i.e. once the queue was full you'd need to set the last element to null when you pop one and move the rest.
When you pushed the element you need to return from the method:
public void push(int x) {
for (int i = 0; i < length; i++) {
if (arr[i] == null) {
arr[i] = x;
return; // Exit from push when you added the element in the right position
}
}
}
Note that this code is not optimized. Push an element requires O(n), so can waste a lot of time for big queues, but this is the closest solution to your code. Anyway a simple optimization can be done introducing a variable holding the last used index. So you can use that variable to push and pop an element in O(1).
I'm trying to iterate over an Object array. Using the next() method works so I'm guessing that my iterator class and constructors are working.
For some reason i'm not getting any output while the hasNext() method is running.
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
With "hej" being my Object array.
My code for the next(); and hasNext() methods are as follows:
public class StackIterator implements Iterator<Object>{
// fields
private int element = 0;
private final Object[] elements;
private final int max;
// constructor
public StackIterator(Object[] values, int maxIndex) {
elements = values;
max = maxIndex;
}
// methods
public boolean hasNext() {
return element < max;
}
public Object next() {
return elements[element++];
}
}
The file that constructs the Object Array and the Object Array depends on an interface:
public interface Stack {
int size();
boolean isEmpty();
void push(Object element);
Object pop();
Object peek();
Iterator<Object> iterator();
}
The methods are then explained in another file:
public class StackExample implements Stack {
// fields
int length = 0;
Object[] arr;
// constructor
public StackExample() {arr = new Object[length];}
// method returns size of object array
public int size() {
return arr.length;
}
// method checks if object is empty
public boolean isEmpty() {
boolean result = false;
if (arr.length == 0){
result = true;
}
return result;
}
// method for push
public void push(Object element) {
newBiggerObj();
arr[0] = element;
}
// returns the first object of the stack
public Object pop() {
Object[] temp = new Object[arr.length-1];
Object first = arr[0];
for (int i = 0; i<arr.length-1; i++){
temp[i] = arr[i+1];
}arr = temp;
return first;
}
// returns the object on top of stack
public Object peek() {
if (isEmpty()){
try{
throw new Exception("Stack empty, can't peek!");
}
catch(Exception e){
return e.getMessage();
}
}
else {
Object first = arr[0];
return first;
}
}
// method for push method
private void newBiggerObj(){
Object[] temp = new Object[arr.length+1];
for (int i = 0; i<arr.length; i++){
temp[i+1] = arr[i];
}
arr = temp;
}
public String toString(){
String str = "";
for (int i = 0; i < arr.length; i++){
str = str + arr[i] + " , ";
}return str;
}
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
}
What bothers me is that the method Iterator is within itself returning an instance of the class Stack Iterator. Which i posted above. So my real problem seems to be that my fields are not being given any value, since I am not myself giving the any values within the constructor.
My main method in which I'm testing all of this is as follows:
public class Teststack {
public static void main(String[] args){
// new instane of class StackExample
StackExample hej = new StackExample();
// test for the different methods
System.out.println(hej.isEmpty());
System.out.println(hej.size());
hej.push(4);
hej.push("hej");
hej.push(6);
hej.push(5);
System.out.println(hej.size());
System.out.println(hej.peek());
System.out.println(hej.pop());
System.out.println(hej.toString());
System.out.println(hej.isEmpty());
System.out.println("Testing Iterator: ");
// test for iterator
Iterator it = hej.iterator();
Object j = it.next();
System.out.println(j);
while(it.hasNext()){
Object i = it.next();
System.out.println(i + " ");
}
}
}
In your StackExample class, I don't see the length variable being updated when elements are pushed or popped. Due to this, length will always be 0 and calls to it.hasNext() will always return false.
You don't need to pass the length as a separate argument. You can find the array's length in the StackIterator constructor and use it.
Also note that since you're creating a new array on every push and pop, the iterator returned by StackExample#iterator() will become stale after every push/pop since it will work on an old copy/state of the stack.
The problem is here:
public Iterator<Object> iterator() {
return new StackIterator(arr, length);
}
length field is never changed, so its value is always 0. You can change the code to this:
public Iterator<Object> iterator() {
return new StackIterator(arr, arr.length);
}
Also, before retrieving elements from the iterator, you should always call it.hasNext. The fact you did this:
Iterator it = hej.iterator();
Object j = it.next();
And worked was just pure luck.
Apart of this, I can sense you have a bad design on your stack implementation. Here are some hints to improve your code:
The inner array should be initialized with a default size different than 0. E.g. 10 (as done in java.util.ArrayList implementation).
You should avoid creating a new array when adding (push) or removing (pop) an element from your stack. Instead of this, you should use the length field to control how many elements are in your stack.
The value of the new size should be based on another formula rather than array.length + 1. For example, try using something like int newSize = array.length / 2 * 3;.
Resize the inner array only when necessary. When calling push, do it only if you precisely need to increase the size of the array. When calling pop, do it if the current length of the array (this is, array.length) is far greater than the value of length field of your class.
Never forget to update the value of length on push and pop methods.
Couple of issues:
You are calling Object j = it.next(); after creating iterator and then check for hasNext. You are incrementing the element index. Hence if you just have one element, you wont enter the while loop. In addition, if your custom datastructure is empty i.e. array has no elements then you are prone to ArrayIndexOutOfBoundException.
You will always iterate and print n-1 elements instead to n elements.
Once you iterated, then your pointer will always point to last element and never get resetted. So very next time you wont be able to iterate over your elements. Its a one time iterator.
Try not to call
Object j = it.next() statement, but just while cycle. Seems you have an array of just 1 element.
There are a number of problems with this code:
In the StackIterator constructor there is no bounds checking on maxIndex. Callers can pass in a number greater than values.length, less that 0, etc.
In the next method, there is no check of the end condition, either directly or by calling hasNext(). Callers can keep calling next() and see elements beyond max or even get an ArrayIndexOutOfBoundsException, when they should be getting a NoSuchElementException.
The Stack class never increments or decrements its length field when elements are pushed or popped.
The Stack class tracks the length separately from the array, even though it always resizes the array on every push or pop, but Java arrays already know their size. (But see the next item.)
The Stack class resizes the array on every push or pop, which is very inefficient. Typically classes like this only resize the array when necessary, allowing 'slack' space, to give amortized constant time performance (see ArrayList). If you do this, however, it is necessary to null out popped items to avoid unintentional object retention.
The Stack adds and removes elements at the beginning of the array. This is incredibly inefficient since it means a O(n) reshuffling must be done on every push or pop.
The peek() method takes into account the possibility that the Stack may be empty, but the pop() method does not. A pop() on an empty Stack will throw an ArrayIndexOutOfBoundsException.
Stack is not a generic class. It holds Object. Users of the Stack will have to cast the return values from peek() or pop(), and it isn't type safe. In your example, you show a stack that is a heterogeneous mixture of String and Integer. This is a very Java 1.2 way of doing things, and while it isn't necessarily wrong, you should consider parameterizing Stack.
I want to rearrange an ArrayList by iterating through it and copying each element to a specific place in a new list.
In this case I want to move an element to the end of the list. For example, if the list is ABCDE and j == B then the new list should be ACDEB.
Here's my code:
private ArrayList<Job> schedule;
private ArrayList<Job> tempSchedule;
...
schedule = input;
tempSchedule = new ArrayList<Job>(schedule.size());
...
private void moveJob(int j) {
for(int i = 0; i < schedule.size(); i++) {
if(i == j) { //move to the end
tempSchedule.set(schedule.size()-1, schedule.get(i));
} else {
if(i > j && i <= schedule.size() -1) { //move one position back
tempSchedule.set(i - 1, schedule.get(i));
} else { //same position
tempSchedule.set(i, schedule.get(i));
}
}
}
schedule = tempSchedule;
u++;
}
Right now I get an IndexOutOfBoundsException: Index: 0, Size: 0 at tempSchedule.set
I guess the problem is with this line
tempSchedule = new ArrayList<Job>(schedule.size());
Also please explain how to make deep copies.
Edit: Thanks for all the answers. I got it to run by simply removing the item and adding it at the end, like suggested.
The reason I wanted to construct a new list is because I might have to do more complex rearrangements at some point.
First, go read the javadoc on ArrayList and collections.
new ArrayList(capacity) doesn't copy, it just allocates a list with that capacity. To copy the list (and it's not a clone, it's a by reference copy, again you need to go back to basics) would be new ArrayList(oldArrayList).
Secondly, Your test has size 0, so there's no objects in it, so get(0) (correctly and as per spec) throws an index out of bounds exception because your list is empty.
Beyond that, neither set nor get will modify the list, so if you had created your copy correctly and it's contents were ABCD and you executed that operation, it's contents would then be ABCB. what you want is.
X = tempSchedule.remove(i) // removes element at I
tempSchedule.add(X) // adds element to end of list
tempSchedule is initialized to be empty:
tempSchedule = new ArrayList<Job>(schedule.size());
You can't use set on an empty ArrayList. It expects the index you are replacing to already have a value.
You get the exception in this line - tempSchedule.set(i, schedule.get(i)); - when i==0.
set calls RangeCheck :
/**
* Checks if the given index is in range. If not, throws an appropriate
* runtime exception. This method does *not* check if the index is
* negative: It is always used immediately prior to an array access,
* which throws an ArrayIndexOutOfBoundsException if index is negative.
*/
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
}
As you can see, the index you pass to it must be smaller than the current size of the list.
The problem is that your tempSchedule list is empty. set() overwrites the element at the given position. If your list is empty, it can't do that.
This might be a little confusing since you wrote new ArrayList<Job>(schedule.size()). But the parameter you are passing doesn't set the size but the initial capacity, meaning the initial size of the underlying array, which can be used before it has to be resized.
Reason is when you define arrayList with size of schedule, its an empty list i.e. contains nothing.
So when you try to set an element (which is used to replace the existing element), it compares the index with size of your list and finds that index is 0 and size is 0 as well.
Note just by passing size as constructor, you are not changing the size of arrayList. So in order to avoid this, you need to use:
tempSchedule = new ArrayList<Integer>(schedule);
instead of
tempSchedule = new ArrayList<Integer>(schedule.size());
You have the IndexOutOfBoundsException because you are using schedule.size in your for loop while it's null you have to use tempSchedule.size instead.
And you are comparing i and j while you have to compare tempSchedule.get(i) and j.
You have a syntax fallacy as every other answer stated.
I'm more concerned on your approach.
Can't you just simply do:
private void moveJob(int j) {
Job toMove = tempSchedule.get(j);
tempSchedule.remove(j);
tempSchedule.add(toMove);
}
Or yet more concise:
private void moveJob(int j) {
tempSchedule.add(tempSchedule.remove(j));
}
I am working on a Linked Lists assignment for my OOP class, and have run into some trouble with a remove method. Our professor has asked us to write a method:
public Object removeElement(int index)
This takes an index, which is the location of the element that needs removed. It must return the data the deleted node contained as well. However, I am having trouble with getting the method to return the object it is removing. For some reason I keep getting the error that the method must return a result of type object. I have it returning an object, and I've gone through trial and error in various spots with no success.
Here is my code:
public Object removeElement(int index)
{
ListIterator iterator = listIterator();
Object object;
//If the supplied index is less than zero, throw an exception.
if(index < 0)
{
IndexOutOfBoundsException ex = new IndexOutOfBoundsException();
throw ex;
}
else
{
for(int i = 0; i <= index; i++)
{
if(!iterator.hasNext())
{
IndexOutOfBoundsException ex = new IndexOutOfBoundsException();
throw ex;
}
else
{
if(i == index)
{
object = iterator.next();
iterator.remove();
return object;
}
else
{
iterator.next();
}
}
}
}
}
You have it returning an object if i == index. But the compiler doesn't know that the loop will actually always end at that point. It's looking at the bottom of the loop and thinking "What do we want to return if we get here?"
I would actually restructure your code to:
if (index < 0)
{
// No need for a separate variable
throw new IndexOutOfBoundsException();
}
// No need for an else block
ListIterator iterator = listIterator();
Object current = null;
for (int i = 0; i <= index; i++)
{
// Note: assuming you expose the size(), you could check this up front...
if(!iterator.hasNext())
{
throw new IndexOutOfBoundsException();
}
current = iterator.next();
}
iterator.remove();
return current;
Now you always call remove and return when you've called next() the given number of times, because that's when the loop will end other than via an exception.
Firstly do not use iterator from java LinkedList it is Doubly linked list , I think professor wants to see how you implement remove functionality for LikedList data structure.
Secondly make loop and condition where i+1 == index in this place, save current element for return like Node returnElement = curent.next; and make delete manipulation curent.next = curent.next.next;
Pls post listIterator() method implementation and the error message that you are getting.
Note:> You have to manage the size of the list using an class variable such as an integer. So you dont have check !iterator.hasNext(), instead compare index with current size.
I need to fill a stack from an array, then print out the elements in order and then again reversing the order. What I'm having problems with is I'm getting an ArrayIndexOutOfBoundsException and cant figure out where it is coming from. I have tried running through the debug and it appears as I'm popping off elements it never reaches the last element. Below is my code:
public class arrayStack {
private int top;
private String[] storage;
public arrayStack(int capacity)
{
storage = new String[capacity];
top = -1;
}
public boolean isEmpty() {
return (top == 0);
}
String peek() {
return storage[top];
}
String pop() {
top--;
return storage[top];
}
public void push(String str) {
top++;
storage[top] = str;
}
}
StackMain.java:
public class StackMain {
public static void main(String[] args) {
//int j = 5;
String[] list = new String[5];
list[0] = "Beware";
list[1] = "The";
list[2] = "Ides";
list[3] = "Of";
list[4] = "March";
arrayStack stack = new arrayStack(5);
for(int i = 0; i < list.length; i++)
{
stack.push(list[i]);
}
for(int j = 0; j < list.length; j++)
System.out.println(stack.pop());
}
}
In pop(), you need to return the item that was popped, which is the item at the index of the old value of top. Cleanest way is to change the function to
String pop() {
return storage[top--];
}
Edit
You also need to change isEmpty() to return (top == -1). You could also change the implementation to use size (the number of elements) instead of top (the index of the highest element) like others mentioned.
In your constructor for arrayStack, you should set top to 0, rather than to -1. In your isEmpty method, you even check that top == 0, so clearly top == 0 means empty, rather than top == -1. This is why you always miss the last element when popping off values from the stack; putting the first element increments top to 0.
Oh, and I missed what tom said, below: decrementing top before you find the value at the top will return the wrong element. His code below is preferable, but this might be more easy to understand for a beginner:
public String pop() {
String topValue = storage[top];
top--;
return topValue;
}
If you push(String) just one element, with top initialized to -1, what will the value of top be after the push?
Now look at your pop() function, it decrements top before trying to get the element requested, so what array index is it going to try to access if you've pushed just one element?
Since you start top at -1, once you have added your 5 elements from the String array top will be 4, which is incorrect since you have 5 elements.
Then when you try to pop the stack 5 times, top goes back to -1 and storage[-1] doesn't exist so you get an ArrayIndexOutOfBoundsException
Start top at 0.
Alternatively if you decrement top after you retrieve the element from you stack, you won't get an error; but it would be better to start top at 0 because top is really representing the number of elements in your stack.
Please tag the question as homework. And coming to the problem, the problem is in the pop() function. You are decrementing the value of top first and then returning the element. But when you check the push() function, you are incrementing first and then adding the element. So, if you move the top-- to after getting the element from the stack your problem will be solved.
Your pop method is incorrect. In your code here, top starts at negative 1.
When you push an element, top becomes 0.
When you pop an element, the top becomes -1 before you access the element.
Also, your empty method is incorrect. In the initial state of the stack, top = -1, and isEmpty checks if it returns 0. Initially the stack should be empty.
your pop() function must be changed. You must store storage[pop] in a temporary variable and then reduce top by 1 and then return the temporary variable
It would be great if you can include java 1.5 generics facility to implement stack.Then your stack will be more flexible.It can hold any type of objects(in you case only Strings)
And one more advice is in the pop method you should tell garbage collector to discard to poped object as follows. (In the case if you are using generics) Following is a more flexible stack implementation which mentioned in effective java edition 2.
// Initial attempt to generify Stack = won’t compile!
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = (E[])new E[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size==0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}