In Java an array has a fixed size (after initialisation), meaning that you can't add or remove items from an array.
int[] i = new int[10];
The above snippet mean that the array of integers has a length of 10. It's not possible add an eleventh integer, without re-assign the reference to a new array, like the following:
int[] i = new int[11];
In Java the package java.util contains all kinds of data structures that can handle adding and removing items from array-like collections. The classic data structure Stack has methods for push and pop.
Answer from Kennet on Stack OverflowIn Java an array has a fixed size (after initialisation), meaning that you can't add or remove items from an array.
int[] i = new int[10];
The above snippet mean that the array of integers has a length of 10. It's not possible add an eleventh integer, without re-assign the reference to a new array, like the following:
int[] i = new int[11];
In Java the package java.util contains all kinds of data structures that can handle adding and removing items from array-like collections. The classic data structure Stack has methods for push and pop.
For those who don't have time to refactor the code to replace arrays with Collections (for example ArrayList), there is an alternative. Unlike Collections, the length of an array cannot be changed, but the array can be replaced, like this:
array = push(array, item);
The drawbacks are that
- the whole array has to be copied each time you push, and
- the original array
Objectis not changed, so you have to update the variable(s) as appropriate.
Here is the push method for String:
(You can create multiple push methods, one for String, one for int, etc)
private static String[] push(String[] array, String push) {
String[] longer = new String[array.length + 1];
for (int i = 0; i < array.length; i++)
longer[i] = array[i];
longer[array.length] = push;
return longer;
}
This alternative is more efficient, shorter & harder to read:
private static String[] push(String[] array, String push) {
String[] longer = new String[array.length + 1];
System.arraycopy(array, 0, longer, 0, array.length);
longer[array.length] = push;
return longer;
}
[JAVA] How Do I Use push() and pop() With an Array?
java howto ArrayList push, pop, shift, and unshift - Stack Overflow
java - Why is ArrayList not a Stack - Software Engineering Stack Exchange
java - Stack using an array - Code Review Stack Exchange
Videos
I've seen that you can use the Stack utility to create a stack which allows the push(), pop(), peek(), and empty() but how can I use these with an array? I am more familiar with using JS and still getting hung up on what Java utilities are used for what.
ArrayList is unique in its naming standards. Here are the equivalencies:
Array.push -> ArrayList.add(Object o); // Append the list
Array.pop -> ArrayList.remove(int index); // Remove list[index]
Array.shift -> ArrayList.remove(0); // Remove first element
Array.unshift -> ArrayList.add(int index, Object o); // Prepend the list
Note that unshift does not remove an element, but instead adds one to the list. Also note that corner-case behaviors are likely to be different between Java and JS, since they each have their own standards.
I was facing with this problem some time ago and I found java.util.LinkedList is best for my case. It has several methods, with different namings, but they're doing what is needed:
push() -> LinkedList.addLast(); // Or just LinkedList.add();
pop() -> LinkedList.pollLast();
shift() -> LinkedList.pollFirst();
unshift() -> LinkedList.addFirst();
We can only guess why the JCF looks today like it does, but one lesson learned in design is what Antoine de Saint-Exupery once said:
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.
In my experience, this applies to software design as well. A component like an ArrayList does not become necessarily "better" by supporting as many different data type interfaces as possible (even if it could). The smaller the interface of a component is, the less do we we have to learn and remember how it looks like, and the less functions are there which we confuse for each other. (Of course, an interface should not be smaller than it needs to be to form a coherent abstraction.)
How "small" an interface of a container should be ideally is definitely a question of the designers experience, taste and what they have learned at school or university. The usual CS books about stacks, lists, vectors, queues and arrays treat them as distinct abstract data types, so following that tradition and implementing them as different classes seemed to be quite natural.
Hence, for some reason we do not know for sure, the JCF designers seemed to have thought peek and pop are negligible for ArrayList. But when you think peek and pop would be a great addition to your ArrayLists, feel free to implement your own component ExtArrayList which provides the whole ArrayList together with peek and pop.
Have you seen this?
Stack Overflow - Rule of thumb for choosing an implementation of a Java Collection?
So tell me, how did you land on ArrayList if you wanted to treat it like a LIFO or a queue?
I know ArrayList is popular. If you got stuck with it somehow and don't really have a choice of implementation don't feel bad about wrapping it up in something that lets its client treat it like a stack. It might not be the most performant choice but good enough is good enough.
But don't act like every possible interface that could have been backed by ArrayList should be native to ArrayList. That list of interfaces has no end. They focused on what they made it for and hoped the kitchen sink could be added later.
Also how would anyone know which end list.pop() would pop from? What makes stack so special? Sorry but if I can see the ArrayList behind the stack then your abstraction is leaking.
First of all, you are using a static variable (growthmultipler) inside the instance of a class. This is fatal if you have more than one instance of this class. Because you always use 2*growthmultipler, you don't need it. Use +=2 instead.
You don't need to prealloc data in the constructor. It will be done if it's needed.
You don't need to handle "size == 0" separately. You only have to handle "size >= length".
You don't have to create a new class if you want to grow data.
In pop() you should test to not get negative (and throw an exception). And normally a pop function returns the value.
In summary it might look like this:
public class stackAlist{
int[] data;
int size;
public stackAlist(){
size = 0;
data = new int[size];
}
public void push(int value){
if(size>=data.length) {
int [] ndata = new int[data.length+2];
System.arraycopy(data, 0, ndata, 0, size);
data = ndata;
}
data[size] = value;
size += 1;
}
public int pop() {
int ret=0;
if(size>0) {
size -= 1;
ret = data[size];
data[size] = 0;
}
return ret;
}
.....
A couple things to add:
- Classes should use CamelCase and should preferably have descriptive names.
stackAlistwould be better namedArrayStack. - You might want to have a
Stackinterface thatArrayStackimplements. - You might want to extract the resizing code into a separate method, and optionally make it public and/or take parameters.
- In your pop method, there's no need to zero out the popped items.
