Why did I have to invoke super.isEmpty()? I have tried this.isEmpty(), but the debug process is paused.
import java.util.*;
public class Stack<e> extends ArrayList<e> {
/**
*
*/
private static final long serialVersionUID = 1L;
public void showPrompt(){
System.out.println("Please input informations five times and type Enter between each gap:");
}
// `enter code here`
public e peek(){
return get(size()-1);
}
public void push(e o){
add(o);
}
public e pop(){
e o=get(size()-1);
remove (size()-1);
return o;
}
public boolean isEmpty(){
return super.isEmpty();
/* Why did I have to invoke super.isEmpty()? */
}
public String toString(){
return "stack"+toString();
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Stack<String> s=new Stack<>();
s.showPrompt();
Scanner scan=new Scanner(System.in);
for(int i=0;i<5;i++){
s.push(scan.next());
}
System.out.println("Reverse order is:");
while(!s.isEmpty()){
System.out.println(s.pop());
}
}
}
We are talking about this method:
public boolean isEmpty() {
return super.isEmpty();
}
First of all, this method as written is unnecessary1. It is simply calling the isEmpty() method in the superclass; i.e. ArrayList. If you left it out, calls to isEmpty() on a Stack would go directly to the isEmpty() method implemented in the superclass.
Now to your question as to why super is necessary. The answer is that if you don't use super here, and write it like this:
public boolean isEmpty() {
return this.isEmpty(); // INCORRECT!
}
then the isEmpty() method will be calling itself. That causes infinite recursion, and leads to a StackOverflowError. (If you looked at the stacktrace you would see a long sequence of stack frames where isEmpty() calls isEmpty() calls isEmpty() .... and so on. Eventually, you run out of stack space().)
By using super, we are telling Java to call the isEmpty method implemented in the superclass.
1 - This code is not the standard implementation of java.util.Stack. The standard Stack class extends Vector and is doesn't declare an override for isEmpty()
Related
So our homework was to implement a stack on our won and then write test cases for it.
This is the stack:
import java.util.Vector;
class Stack<T> extends Vector<T> {
private Vector<T> stack;
Stack() {
stack = new Vector<T>();
}
// returns false or true, given the stack is empty or not.
public boolean isEmpty() {
return stack.size() == 0;
}
//returns the top element of the stack without removing it.
public T peek() {
return stack.get(stack.size()-1);
}
//puts a new element to the top of the stack
public void push(T element) {
stack.add(element);
}
//returns and removes the top element of the stack
public T pop() {
return stack.get(stack.size()-1);
}
}
And this is my test class so far.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class StackTest {
#Test
void isEmpty() {
stack s = new stack<Integer>;
assertEquals(true, s.isEmpty());
}
#Test
void peek() {
Stack t = new Stack(1);
}
#Test
void push() {
}
#Test
void pop() {
}
}
I am really having trouble figuring out what is wrong with the first two test methods. Does anybody else have an idea?
This is wrong:
//returns and removes the top element of the stack
public T pop() {
return stack.get(stack.size()-1);
}
You don't remove the element, use remove instead of get
Other errors:
void isEmpty() {
//Typo errors here, s is uppercase and missing parenthesis
stack s = new stack<Integer>;
assertEquals(true, s.isEmpty());
}
#Test
void peek() {
//What does Stack(1) mean? There is no such constructor in class
Stack t = new Stack(1);
}
Also:
//If you already extend Vector you don't need a Vector field for the data
class Stack<T> extends Vector<T> {
private Vector<T> stack;
Suppose you have given a class in Java that extends the Iterable interface. This class has to provide an Iterator that should return the instance of the surrounding class, take a look at the main method.
public class Test implements Iterable<Test> {
#Override
public Iterator<Test> iterator() {
return new Iterator<Test>() {
private boolean onlyOnce = false;
#Override
public boolean hasNext() {
return false;
}
#Override
public Test next() {
if (!onlyOnce) {
onlyOnce = true;
// TODO return
}
throw new NoSuchElementException("Iterator has already been called");
}
};
}
public static void main(String[] args) {
Test test = new Test();
Test test2 = test.iterator().next();
boolean b = test == test2; // should be true
}
}
How could this issue be solved in Java?
In order to return the enclosing instance of Test, use a qualified this:
return Test.this;
However, a much neater way to implement the method would be to use an existing iterator implementation:
#Override
public Iterator<Test> iterator() {
return Arrays.asList(this).iterator();
// or Collections.singleton(this).iterator()
// or Stream.of(this).iterator()
// or many other possibilities.
}
I'm trying to teach myself some java and im stuck on a problem that seems kind of easy but i still don't seem to find a solution.
What I have so far:
Interface:
public interface ADTStack<T> {
public boolean isEmpty();
public void push(T element);
public T top() throws IllegalStateException;
public void pop() throws IllegalStateException;
}
Class Stack:
public class Stack<T> implements ADTStack<T> {
private java.util.LinkedList<T> data;
public Stack() {
data = new java.util.LinkedList<T>();
}
#Override
public boolean isEmpty() {
return data.isEmpty();
}
#Override
public void push(T element) {
data.add(0, element);
}
#Override
public T top() throws IllegalStateException {
if (isEmpty()) {
throw new IllegalStateException("Stack is emtpy.");
}
return data.getFirst();
}
#Override
public void pop() throws IllegalStateException {
if (isEmpty()) {
throw new IllegalStateException("Stack is empty.");
}
data.remove(0);
}
Alright , so here is what I'm trying to do.
I'm trying to write a methode equals to compare two Stacks.
My idea was to use a third Stack to be able to bring both stacks into
their original state after comparing them.
Here's what I have:
Stack supportStack = new Stack();
public boolean equals(ADTStack<T> s){
if (data.isEmpty() != s.isEmpty()){
return false;
}
if (data.isEmpty() && s.isEmpty()){
return true;
}
T element_a = this.top();
T element_b = s.top();
if( (element_a ==null && (element_b !=null) || !element_a.equals(element_b) || element_a != null && element_b == null)){
return false;
}
data.pop();
s.pop();
supportStack.push(element_a);
boolean result = data.equals(s);
while (!supportStack.isEmpty()){
data.push(supportStack.top());
s.push(supportStack.top());
supportStack.pop();
}
return result;
}
I get a lot of errors when I compile the code and it seems that something is wrong with :
Stack supportStack = new Stack();
I don't really know what's wrong and how to solve the error. I made a runner-class and I tried the constructor and it worked so I'm confused at what's wrong.
public class Runner {
public static void main(String[] args){
Stack test = new Stack();
test.push(12);
System.out.println(test.top());
}
}
I gladly take any advice or constructive criticism since I'm teaching myself and if anything seems unclear feel free to ask.
Stack supportStack = new Stack();
Stack is called a raw type: it's like not using generics. You need to use:
Stack<T> supportStack = new Stack<T>();
But, as a hint: you don't need to do this. You can just do:
return this.data.equals( s.data );
I'm trying to compile the following program and keep receiving an abstract method error. The program I'm trying to compile is as follows (not yet complete though). The error I'm receiving is as follows:
Double.java:5: error: Double is not abstract and does not override abstract method getNext() in ListInterface
public class Double<T extends Comparable<T>> implements ListInterface<T>{
^
where T is a type-variable:
T extends Comparable<T> declared in class Double
1 error
import java.io.*;
import ch06.lists.*;
import support.DLLNode;
public class Double<T extends Comparable<T>> implements ListInterface<T>{
protected DLLNode<T> front;
protected DLLNode<T> rear;
protected DLLNode<T> curPosition;
protected int numElements;
public Double(){
front = null;
rear = null;
curPosition = null;
numElements = 0;
}
protected DLLNode<T> find(T target){
}
public int size(){
return numElements;
}
public boolean contains(T element) throws NullPointerException{
if (DLLNode.getInfo()!=element){
return false;
}
else{
return true;
}
}
public boolean remove(T target) throws StackUnderflowException{
if (!contains(target)){
return false;
}
else{
return true;
DLLNode.setLink()==null;
}
}
public T get(T element){
return find(element);
}
public String toString(){
}
public void reset(){
}
#Override
public T getNext(){
return null;
}
public void resetBack(){
}
public T getPrevious(){
}
public void add(T element){
}
}
There are a lot of errors here.
Some:
1.
protected DLLNode<T> find(T target){
needs to return something.
2.
public String toString(){
needs to return something.
3.
public T getPrevious(){
needs to return something.
4.
protected DLLNode<T> find(T target) {
while
public T get(T element) {
return find(element);
}
see that get() returns T and find() returns DLLNode<T>
Compiler just got confused with all that and told you to fix at least something :)
Got it!
You are missing a } at:
public boolean remove(T target) throws StackUnderflowException{
if (DLLNode.contains()==target){
return true;
DLLNode.setLink()==null;
}
Although I don't really understand what you try to do here...
in:
public boolean remove(T target) throws StackUnderflowException{
if (!contains(target)){
return false;
}
else{
return true;
DLLNode.setLink()==null;
}
}
You cannot return a value and execute another command after. Switch the order of return & DLLNode.setLink()==null;
It says you are not overriding the getNext() method in ListInterface, and currently you have two getNext() methods. I'm surprised it's not telling you about that, but I guess it's looking at the first one and seeing it's not the same as what it expects from ListInterface.java. Delete the public DLLNode<T> getNext() method, and the error should go away.
The real solution to your problem is to get yourself a good IDE, like Eclipse or IntelliJ. They will highlight where all the problems are in your code and give you suggestions on how to fix them. Generally the hardest part in using an IDE is getting it set up properly, so I'd suggest doing a search for a tutorial for whatever IDE you decide.
let's say I have this simple MyArray class, with two simple methods: add, delete and an iterator. In the main method we can see how it is supposed to be used:
public class MyArray {
int start;
int end;
int[] arr;
myIterator it;
public MyArray(){
this.start=0;
this.end=0;
this.arr=new int[500];
it=new myIterator();
}
public void add(int el){
this.arr[this.end]=el;
this.end++;
}
public void delete(){
this.arr[this.start]=0;
this.start++;
}
public static void main(String[] args){
MyArray m=new MyArray();
m.add(3);
m.add(299);
m.add(19);
m.add(27);
while(m.it.hasNext()){
System.out.println(m.it.next());
}
}
And then MyIterator should be implemented somehow:
import java.util.Iterator;
public class myIterator implements Iterator{
#Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
#Override
public Object next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
MyIterator should iterate arr from MyArray class, from start to end values; both are also attributes of MyArray. So, as MyIterator should use MyArray attributes, how should MyIterator be implemented? Perhaps I can send the current object in the initialization:
it=new myIterator(this);
But I guess it's not the best soultion. Or maybe MyArray itself should implement Iterator interface? How is this solved?
EDIT:
Ok, thanks to everybody. This was a simple example of what I wnat to do, so don't care about fixed length array. Waht I really want to do is a circular FIFO, that's why start and end are the cursors.
This circular FIFO will be an array of pairs of ints with, e.g., size 300: int[][] arr=new int[300][2].
When iterating a circular array I have to take care if the counter arrives to the end and make it start from the beginning, so this is how I have solved it:
if (this.start >= this.end ) temp_end=this.end+this.buff.length;
else temp_end=this.end;
int ii;
int j=0;
int[] value=new int[2];
for(int i=this.start; i<temp_end; i++){
ii=i% this.arr.length;
value=this.buff[ii];
//do anything with value
}
But I would like to avoid worrying about these things and just iterate in a simple way, I can do this with iterator interface, but then I have 2 problems: the first one I already explained and has been solved by many answers, and the second one is that my array is made of pairs of ints, and I can't use iterator with primitive types.
Its very unusual to maintain an iterator as an instance variable of the class. You can only traverse the array once - probably not what you want. More likely, you want your class to provide an iterator to anyone that wants to traverse your array. A more traditional iterator is below.
Java 5+ code - I haven't tried to compile or run, so it may be contain errors (not near a dev machine right now). It also uses autobox'ing for converting Integer to int.
public class MyArray implements Iterable<Integer> {
public static class MyIterator implements Iterator<Integer> {
private final MyArray myArray;
private int current;
MyIterator(MyArray myArray) {
this.myArray = myArray;
this.current = myArray.start;
}
#Override
public boolean hasNext() {
return current < myArray.end;
}
#Override
public Integer next() {
if (! hasNext()) throw new NoSuchElementException();
return myArray.arr[current++];
}
#Override
public void remove() {
// Choose exception or implementation:
throw new OperationNotSupportedException();
// or
//// if (! hasNext()) throw new NoSuchElementException();
//// if (currrent + 1 < myArray.end) {
//// System.arraycopy(myArray.arr, current+1, myArray.arr, current, myArray.end - current-1);
//// }
//// myArray.end--;
}
}
....
// Most of the rest of MyArray is the same except adding a new iterator method ....
public Iterator<Integer> iterator() {
return new MyIterator();
}
// The rest of MyArray is the same ....
}
Also note: be careful of not hitting that 500 element limit on your static array. Consider using the ArrayList class instead if you can.
In my opinion it is better to implement MyArray as common Iterable object, so it can be used in a for statement.
My suggestion:
/**
* My array
*/
public class MyArray<TItem> implements Iterable<TItem>
{
/**
* Internal used iterator.
*/
private class MyArrayIterator<TItem> implements Iterator<TItem>
{
private MyArray<TItem> _array;
/**
* #param array The underlying array.
*/
public MyArrayIterator(MyArray<TItem> array)
{
this._array = array;
}
/**
* Gets the underlying array.
*
* #return The underlying array.
*/
public MyArray<TItem> getArray() {
return this._array;
}
#Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
#Override
public TItem next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
public void add(int el){
// do add
}
public void delete(){
// do delete
}
#Override
public Iterator<TItem> iterator() {
// TODO Auto-generated method stub
return new MyArrayIterator<TItem>(this);
}
}
As I said you can use it in a for statement:
private static void test(MyArray<String> strArray)
{
for (String str: strArray) {
// do something
}
}
Iterator is an interface . Iterator<E> which means only Object can go here (E) .
Iterator<Integer> is legal but Integer<int> is not because int is primitive data type
You can change the array to the ArrayList and then iterate over this arraylist. I added getIterator() method that returns the arraylist.iterator() and test it in main() method
import java.util.ArrayList;
import java.util.Iterator;
public class MyArray {
int start;
int end;
ArrayList<Integer> arr;
public MyArray() {
this.start = 0;
this.end = 0;
arr = new ArrayList<Integer>(500);
}
public void add(int el) {
arr.add(el);
this.end++;
}
public void delete() {
arr.remove(arr.size()-1);
this.start++;
}
public Iterator<Integer> getIterator(){
return arr.iterator();
}
public static void main(String[] args) {
MyArray m = new MyArray();
m.add(3);
m.add(299);
m.add(19);
m.add(27);
Iterator<Integer> it = m.getIterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
My suggestion is to let MyArray implement the interface java.lang.Iterable and create an instance of an iterator per iterator() call (as an anonymous class). Then you can use an instance of MyArray directly in a foreach construct:
public class MyArray implements Iterable {
// ...
// Only arr is needed now as an instance variable.
// int start;
// int end;
int[] arr;
// myIterator it;
/**
* From interface Iterable.
*/
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
// The next array position to return
int pos = 0;
public boolean hasNext() {
return pos < arr.length;
}
public Integer next() {
if(hasNext())
return arr[pos++];
else
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
}
Update: According to BertF's comment I updated my code to make it clear, that the only instance variable for class MyArray is now arr. The state for the iterator is now inside the anonymous Iterator implementation. So you can create multiple iterator instances which don't interfere each other.
EDIT: this does not work for arrays of primitive types:
you could use Arrays for this:
it = new Arrays.asList(arr).subList(start, end).iterator();
END OF EDIT
If you really want to implement your own iterator, I would suggest an internal class in this scenario. This way you can access MyArray.this from myIterator.
public class MyArray {
....
private class myIterator implements Iterator{
....
}
}
MyArray should implement the Iterator as it is also responsible for maintaining the array. Simple encapsulation principle.