Hallo,
ich rätsel seit Stunden an einem Problem herum. Ich wollte zum üben von Iteratoren und Abstrakten Klassen mal einen Stack und eine Queue mit Generics implementieren.
Nun stehe ich vor folgendem Problem. Der Iterator der LinkedList, die im Hintergrund benutzt wird funktioniert einwandfrei. Diesen Iterator gebe ich einfach mit der abstrakten Klasse des Stacks zurück und hatte dann geplannt ihn für die Queue zu überschreiben.
Er funktioniert auch, solange man ihn als Variable zuweist. Wenn ich jedoch mit einer for-each Schleife über den Iterator gehe lande ich bei einem Compilerfehler.
Laut dem Compiler stimmt der Typ nicht überein (Integer != Object). Wenn ich jedoch als Object über den Iterator gehe und mir den Klassennamen anzeigen lasse ist dieser ein Integer.
Ich verstehe dieses Verhalten überhaupt nicht. Ich poste die Datein hier mal. In der Test.java habe ich das ganze auch nochmal kommentiert. Wenn man die for-each Zeile mit dem Integer auskommentiert und kompiliert kann man am Output den Klassennamen Integer sehen.
Ich würde mich wirklich freuen wenn mit jemand dieses Verhalten erklären könnte. Ich find im Internet nichts dazu und bei Stackoverflow konnte man mir auch nicht helfen.
SimpleLinkedList.java
AbstractStack.java
Stack.java
Test.java
ich rätsel seit Stunden an einem Problem herum. Ich wollte zum üben von Iteratoren und Abstrakten Klassen mal einen Stack und eine Queue mit Generics implementieren.
Nun stehe ich vor folgendem Problem. Der Iterator der LinkedList, die im Hintergrund benutzt wird funktioniert einwandfrei. Diesen Iterator gebe ich einfach mit der abstrakten Klasse des Stacks zurück und hatte dann geplannt ihn für die Queue zu überschreiben.
Er funktioniert auch, solange man ihn als Variable zuweist. Wenn ich jedoch mit einer for-each Schleife über den Iterator gehe lande ich bei einem Compilerfehler.
Laut dem Compiler stimmt der Typ nicht überein (Integer != Object). Wenn ich jedoch als Object über den Iterator gehe und mir den Klassennamen anzeigen lasse ist dieser ein Integer.
Ich verstehe dieses Verhalten überhaupt nicht. Ich poste die Datein hier mal. In der Test.java habe ich das ganze auch nochmal kommentiert. Wenn man die for-each Zeile mit dem Integer auskommentiert und kompiliert kann man am Output den Klassennamen Integer sehen.
Ich würde mich wirklich freuen wenn mit jemand dieses Verhalten erklären könnte. Ich find im Internet nichts dazu und bei Stackoverflow konnte man mir auch nicht helfen.
SimpleLinkedList.java
Java:
import java.util.Iterator;
/**
* SimpleLinkedList: A Linked List optimized for the usage in a stack/queue.
*/
public class SimpleLinkedList<E> implements Iterable<E> {
private Node head;
private Node tail;
private Node preTail;
private int size;
/**
* Create a new SimpleLinkedList
*/
public SimpleLinkedList() {
this.size = 0;
this.head = null;
this.tail = null;
this.preTail = null;
}
/**
* Add a new Element at the end of the List.
* @param E Element<T>
*/
public void add(E element) {
Node tmp = new Node(element);
if(this.size == 0) { this.head = tmp; this.tail = tmp; }
else {
this.preTail = this.tail;
this.tail.next = tmp;
this.tail = tmp;
}
size++;
}
/**
* Get first Element
* @return E Element<T>
*/
public E getFirst() {
return (size != 0) ? (E) this.head.data : null;
}
/**
* Get last Element
* @return E Element<T>
*/
public E getLast() {
return (size != 0) ? (E) this.tail.data : null;
}
/**
* Delete first Element
*/
public void removeFirst() {
if(!deleteTrivialCase()) {
this.head = head.next;
size--;
}
}
/**
* Delete last Element
*/
public void removeLast() {
if(!deleteTrivialCase()) {
this.preTail.next = null;
this.tail = this.preTail;
size--;
}
}
/**
* Reset List
*/
public void reset() {
this.head = null;
this.tail = null;
this.preTail = null;
this.size = 0;
}
/**
* Size
* @return int Size of List
*/
public int size() {
return size;
}
/**
* toString representation just like an Array
* @return String List of elements in the list.
*/
@Override
public String toString() {
if(size == 0) { return "null"; }
StringBuilder s = new StringBuilder();
Node tmp = head;
while(tmp != null){
s.append(tmp.data+((tmp.next!=null)?", ":""));
tmp = tmp.next;
}
return "[" + s.toString() + "]";
}
/**
* Iterrator
* @return NodeIterator
*/
@Override
public Iterator<E> iterator() {
return new NodeIterator();
}
/**
* Internal method to deal with trivial deletations.
* @return boolean true if deletation is trivial.
*/
private boolean deleteTrivialCase() {
if(size == 0) { return true; }
if(size == 1) { this.head = null; this.tail = null; size--; return true; }
return false;
}
private class Node {
private E data;
private Node next;
public Node(E data) {
this.data = data;
this.next = null;
}
}
private class NodeIterator implements Iterator<E> {
private Node current = head;
public boolean hasNext() {
return current != null;
}
public E next() {
E cache = (E) current.data;
current = current.next;
return cache;
}
public void remove() {
throw new UnsupportedOperationException("Operation not allowed.");
}
}
}
AbstractStack.java
Java:
import java.util.EmptyStackException;
import java.util.Iterator;
/**
* AbstractStack: Superclass for the Stack and Queue
**/
public abstract class AbstractStack<E> implements Iterable<E> {
SimpleLinkedList<E> list;
AbstractStack() {
this.list = new SimpleLinkedList<E>();
}
/**
* Add element to the underlaying List.
* @param E Element
*/
public void add(E element) {
list.add(element);
}
/**
* Reset the Stack.
*/
public void reset() {
list.reset();
}
/**
* Stacksize
* @return int Stacksize
*/
public int size() {
return list.size();
}
/**
* Stackstate
* @return boolean isEmpty
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* Internal function to deal with access to empty Stacks.
* @throws EmptyStackException
*/
protected void emptyStackSafeguard() {
if(size() == 0) { throw new EmptyStackException(); }
}
/**
* Iterator
*/
@Override
public Iterator<E> iterator() {
return list.iterator();
}
public abstract String toString();
}
Stack.java
Java:
/**
* Stack: Implementation of a Stack using the SimpleLinkedList.
*/
public class Stack<E> extends AbstractStack {
/**
* Create new Stack.
*/
public Stack() {
super();
}
/**
* Push Element onto the Stack.
* @param E Element to push.
*/
public void push(E element) {
super.add(element);
}
/**
* Pop Element out of the Stack.
* @return E Last Element of the Stack.
* @throws EmptyStackException if the Stack is empty.
*/
public E pop() {
super.emptyStackSafeguard();
E cache = (E) list.getLast();
list.removeLast();
return cache;
}
/**
* Return Element without popping it.
* @return E Last Element of the Stack.
*/
public E peak() {
return (E) list.getLast();
}
/**
* String Representation
* @return Stack as String Representation.
*/
@Override
public String toString() {
return (!isEmpty()) ? "Bottom -> " + list.toString() + " <- Top" : "null";
}
}
Test.java
Java:
import java.lang.*;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
SimpleLinkedList<Integer> list = new SimpleLinkedList<Integer>();
Stack<Integer> stack = new Stack<Integer>();
for(int i = 0; i <= 5; i++) {
list.add(i); stack.add(i);
}
//Liste Klappt ohne Probleme
for(Integer l : list) {
l.getClass();
}
System.out.println("--- Mit Iterator:");
//Funktioniert
Iterator it = stack.iterator();
while(it.hasNext()) {
System.out.println(it.next().getClass());
}
System.out.println("--- For Each:");
//Funktioniert + Gibt Integer als Klasse zurück
for(Object z : stack) { System.out.println(z.getClass()); }
//Compilerfehler
for(Integer i : stack) { System.out.println(i.getClass()); }
}
}