Java Stack

Hallo,

ich habe die Vorgabe einen IntStack in Java zu implementieren. Es soll eine Abstrakte Klasse AbstractStack geben, die die üblichen Funktionen einen Stacks wie push, pop, peek, isEmpty usw. bereitstellt.
Der IntStack erbt von AbstractStack und implementiert die Methoden.
Blöd, dass ich in der abstrakten Klasse überhaupt nicht weiß, wer von ihr erbt und mit was für Typen push und peek arbeiten - somit kann ich keine Methodensignatur festlegen.

Der Gedanke war nun Object zu benutzen (siehe Klassendiagramm) - dies gefällt mir jedoch überhaupt nicht und stößt mir auf. Da Generics nicht verwendet werden sollen fällt mir kein anderer Ansatz ein.
Wie mache ich das Design am besten?

Wieso object. Da es ein intStack ist, kommt int. Also push(int) und int pop()

Weil es auch einen StringStack, DoubleStack usw. geben kann. Meinst du ich erstelle für jeden Datentyp in der Abstrakten Klasse eine abstract Method? Das würde keinen Sinn ergeben, da eine Unterklasse IntStack keine Methoden für StringStack implementieren will.

Dann kannst du keinen int stack implementieren. Int is ein primitiver datentyp. Du müsstest wie du schon gesagt hast mit Integer und Generics arbeiten. Da gäbe es schon einen stack von java

Den Performancebonus durch das ersparen des autoboxing würdest du dann aber verlieren. Was die übung m.m.n. ziemlich unnötig macht

D.h. ich liege mit Object trotzdem ‚richtig‘ (unter Berücksichtigung der Vorgaben), da die Primitiven Datentypen ebenfalls Objects sind - auch wenn diese Lösung weh tut?

Primitive datentypen sind eben keine objects. Nur ihre „grossen“ brüder
int - Integer
long - Long
Usw…

Durch autoboxing werden diese dann jeweils umgewandelt. Jedoch mit performanceverlust. Das ist der grund warum eine implementierung eines primitiven stacks sinn machen kann

Ich denke dann muss der Stack in die Unterklasse und explizit int (Vorgabe ist ein int-Array) sein. Das Problem mit den abstrakten Methoden kann ich jedoch nicht lösen.

Ja, weil es so nicht geht.

Mal als Beispiel:

public abstract class Stack {
private Object[] list;
private int stackPointer;

public Stack(int size) {
stackPointer = 0;
list = new Object[size];
}

public Stack() {
this(10);
}

public Object pop() {
if(stackPointer > 0) {
stackPointer--;
Object obj = list[stackPointer];
return obj;
}
else {
throw new NoSuchElementException();
}
}

public void push(Object obj) {
list[stackPointer] = obj;
stackPointer++;
}
}

[CODE]
public class IntStack extends Stack {
public IntStack(int size) {
super(size);
}

public void push(int num) {
super.push(num);
}

public Integer pop() {
return (Integer)super.pop();

}
}[/CODE]

Du kannst so kein int zurückgeben, weil es nicht von Object erbt. Nur Integer. Dies macht jedoch keinen Sinn… Wie schon oben genannt.

Wenn es etwas bringen soll, dann muss alles primitiv sein, aber dann kommst du nicht um die Mehrfachimplementation rum.

Hier eine ältere Implementation einer IntArrayList von mir…
https://gist.github.com/janscheidegger/0de1abd30d9986372aab

Die Performance bei einem add oder remove war nicht gross, aber wenn es darum ging alle miteinander zu addieren, ist dann eine primitive ArrayList viel schneller, wie auch ein primitiver Stack schneller wäre…

Sorry, aber Vorgabe ist weiterhin die Ablage in ein int-Array. Deswegen mein Entschluss im letzten Beitrag, dass das Array in IntStack muss. Selbst mit deiner Inspiration finde ich nichts besseres.

[CODE]public abstract class ADTStack {
private int size;

public ADTStack() {
    this(15);
}

public ADTStack(int size) {
    this.size = size;
}

abstract void init();
abstract boolean isEmpty();
abstract boolean isFull();
abstract void push( Object a );
abstract void pop();
abstract Object top();     

/**
 * @return the size
 */
public int getSize() {
    return size;
}

/**
 * @param size the size to set
 */
public void setSize(int size) {
    this.size = size;
}

}

class IntStack extends ADTStack {

public int stack[];
public int head;

public IntStack(int size) {
    super(size);
    this.head = -1;
}

@Override
void init() {
    this.stack = new int[getSize()];
}

@Override
boolean isEmpty() {
    return this.head == -1;
}

@Override
boolean isFull() {
    return this.head == getSize()-1;
}

@Override
void push(Object a) {
    if( this.head < getSize() ) {
        this.head++;
        this.stack[this.head] = (int) a;
    }
}

@Override
void pop() {
    this.stack[head] = 0;
    if( this.head > -1 ) {
        this.head--;
    }
}

@Override
Object top() {
    if( this.head != -1 ) {
        return (Integer) this.stack[head];
    }
    return null;
}

}[/CODE]