"Dynamischer" Iterator

Status
Nicht offen für weitere Antworten.

Nicole81

Aktives Mitglied
Huhu,

ich habe ein Problem und finde bisher keine schöne Lösung. Vielleicht kann mir jemand weiterhelfen.

Ich habe eine eigene Listenklasse. In dieser Liste können verschiedene Typen von Objekten enthalten sein (Apfel, Birne, Banane usw.). Die Listenklasse ansich stellt einen Iterator zur verfügung um durch alle Elemente zu gehen.
Zusätzlich hätte ich gerne noch einen Typabhängigen Iterator, der je nach Anwendungszweck verwendet werden kann, so in etwa sollte das ausschauen:

Code:
public class Test
{
    public static void main(String[] args)
    {
        MyList myList = new MyList();
		
        myList.add(new Apfel());
        myList.add(new Birne());
        myList.add(new Banane());
        myList.add(new Apfel());
        myList.add(new Apfel());
		
        // normaler Iterator über alle Elemente in der Liste
        for (Frucht f : myList)   
        {
	// funktioniert
        }

        // sowas in der Art soll möglich sein
        // es sollen direkt "Apfel"-Objekte geliefert werden ohne cast
        // die Typen müssen erweiterbar sein
        // wenn möglich ohne redundanten code, d.h. nicht für jeden Typ eine eigene Iteratorklasse
        for (Apfel a : new Iterator<Apfel>(myList))
        {
                 // ???
         }
    }
}

Vielen Dank schon mal!

Liebe Grüße Nicole
 

Ebenius

Top Contributor
Ganz so wird's nicht gehen, da die Typ-Bindungen der Generics zur Laufzweit nicht verfügbar sind. Was gehen würde, wäre so ein Konstruk:
Code:
for (Iterator<Apfel> it = new FilterIterator<Apfel>(Apfel.class, myList); it.hasNext(); ) {
  final Apfel a = it.next();
  // ???
}
Passt das?

[ edit ] Nicht dass das falsch verstanden wird: Diesen FilterIterator muss man erst bauen. Den gibts nicht (bzw. kenne ich nicht) fertig. Aber so wie oben könnte er funktionieren.

[ edit 2 ] Code-Beispiel nochmal angepasst. Ein Iterator passt nicht in die for-each-Schleife.
 
M

maki

Gast
Kannst dir eeinen eigenen Iterator schreiben, fertiges gibt es nix.
Müsstest beim Iterieren prüfen, ob es sich um eine Instanz der "richtigen" Klasse handelt, ansonsten weiteriterieren.

Halte ich persönlich für unschönes Design, wegen der Verwendung des instanceOf operators bzw. des Vergleichs der Klassen selbst.
 

Ebenius

Top Contributor
maki hat gesagt.:
Halte ich persönlich für unschönes Design, wegen der Verwendung des instanceOf operators bzw. des Vergleichs der Klassen selbst.

Sehe ich eigentlich nicht so. Man hat oft den Fall, dass man eine Liste allen Obstes hat und dann an einigen Stellen nur die Äpfel iterieren muss. Ist doch mit nem FilterIterator bestmöglich gelöst...
 
M

maki

Gast
Schon klar Ebenius,

was mir misfällt ist die Abfrage der Typinfo, würde da leiber über eine Interface Methode gehen (boolean isApple()) anstatt die Klasse selbst bzw. instanceOf.

Ist aber wohl geschmackssache.
 

Ebenius

Top Contributor
maki hat gesagt.:
was mir misfällt ist die Abfrage der Typinfo, würde da leiber über eine Interface Methode gehen (boolean isApple()) anstatt die Klasse selbst bzw. instanceOf.

Dann kannst Du's ja nicht generisch lösen. Das wäre eher schlechter als besser, in meinen Augen.

BTW: Es hat Gründe, warum die "Class"-Klasse auch ein parametrisiert ist...
 

Nicole81

Aktives Mitglied
Danke für den Tipp... So hab ich es hinbekommen...

Hab die ganze Zeit versucht den generischen Typ mit den Objekten in der liste zu vergleichen...

Geht so was in der Art wirklich nicht:

if (myObject instanceof T) ??
 

Nicole81

Aktives Mitglied
Hier mal die Klasse schnell implementiet. Tut soweit, geht auch in der verkürzten for-each-Schleife so.

Code:
public class FilterIterator<T> implements Iterable<T>, Iterator<T>
{
	private Class<?> filterClass;
	private MyList list;
	private int position;
	
	public FilterIterator(Class<?> filterClass, MyList list)
	{
		super();
		this.filterClass = filterClass;
		this.list= list;
		position = 0;
	}

	@Override
	public Iterator<T> iterator()
	{
		return this;
	}

	@Override
	public boolean hasNext()
	{
		for (int i = position; i < list.getElementCount(); i++)
		{
			if (list.getElementAt(i).getClass().getName().equals(filterClass.getName()))
			{
				return true;
			}
		}

		return false;
	}

	@SuppressWarnings("unchecked")
	@Override
	public T next()
	{
		for (int i = position; i < list.getElementCount(); i++)
		{
			if (list.getElementAt(i).getClass().getName().equals(filterClass.getName()))
			{
				position = i + 1;
				return (T)list.getElementAt(i);
			}
		}

		position = list.getElementCount();
		return null;
	}

	@Override
	public void remove()
	{
		// not implemented
	}
}

Code:
		for (Apfel a : new FilterIterator<Apfel>(Apfel.class, list))
		{
			a.print();
		}

Edit: Schreibfehler im Code behoben ;-)
 
M

maki

Gast
Ebenius hat gesagt.:
maki hat gesagt.:
was mir misfällt ist die Abfrage der Typinfo, würde da leiber über eine Interface Methode gehen (boolean isApple()) anstatt die Klasse selbst bzw. instanceOf.

Dann kannst Du's ja nicht generisch lösen. Das wäre eher schlechter als besser, in meinen Augen.

BTW: Es hat Gründe, warum die "Class"-Klasse auch ein parametrisiert ist...
Ok, auch wieder richtig.

Also nehme ich alles zurück und behaupte das Gegenteil :)
 

Ebenius

Top Contributor
Weitere Anmerkungen:

1. Entweder es ist ein Iterator oder ein Iterable. Ich würde in der Klasse nur den Iterator beschreiben...

2. Die Typ-Prüfung würde ich genauer machen. Und nimm doch für die liste das List-Interface (oder siehe 3.):
Code:
public class FilterIterator<T> implements Iterable<T>, Iterator<T> 
  { 
     private Class<? extends T> filterClass; 
     private List<? super T> list; 
     private int position; 
      
     public FilterIterator(Class<? extends T> filterClass, List<? super T> list) {

3. Der Iterator ist nicht sicher gegen Concurrent-Modification. Daher sollte man eventuell lieber den FilterIterator auf einem Iterator aufbauen.

Das ist mein Vorschlag (inkl. remove und co-modification check, aber noch ungetestet!):
Code:
public class FilterIterator<T> implements Iterator<T> {

  private final Class<? extends T> clazz;
  private final Iterator<? super T> delegate;
  private T next = null;

  /** Creates a new <code>FilterIterator</code>. */
  public FilterIterator(Class<? extends T> clazz, Iterator<? super T> delegate) {
    this.clazz = clazz;
    this.delegate = delegate;
  }

  @SuppressWarnings("unchecked")
  @Override
  public boolean hasNext() {
    while (next == null && delegate.hasNext()) {
      final Object test = delegate.next();
      if (clazz.isInstance(test)) {
        next = (T) test;
      }
    }

    return next != null;
  }

  @Override
  public T next() {
    final T value = next;
    next = null;
    return value;
  }

  @Override
  public void remove() {
    delegate.remove();
  }
}

[ edit ] hab den clazz-Parameter als "? extends T" abgeändert. Weil's besser ist. :)
 

Nicole81

Aktives Mitglied
Vielen Dank für die Tipps, noch paar Fragen dazu:

zu 1. wenn man "Iterable"´bei dem Iterator nicht implementiert, kann man ihn ja nicht direkt in einer for-each-Schleife verwenden oder? Bzw. was ist falsch oder schlimm daran "Iterable" auch zu implementieren?

zu2. danke, das mit der Typprüfung ist in deiner Version um längen besser gelöst.

zu 3. was genau macht das "super T" bei "Iterator<? super T>"?
wie schützt diese Implementierung vor Concurrent-Modification?

Danke :)
 

Ebenius

Top Contributor
Nicole81 hat gesagt.:
zu 1. wenn man "Iterable"´bei dem Iterator nicht implementiert, kann man ihn ja nicht direkt in einer for-each-Schleife verwenden oder? Bzw. was ist falsch oder schlimm daran "Iterable" auch zu implementieren?

Ich mag's nicht. Ist vielleicht Geschmackssache, weiß nicht. Ein Datenobjekt ist ggf. iterierbar, ein Iterator eigentlich nicht. Ich würde mir eher in MyList sowas hinzu-implementieren (E ist der ElementTyp der Liste):
Code:
public <T extends E> Iterable<T> filteredIterable(final Class<T> type) {
  return new Iterable<T>() {

    @Override
    public Iterator<T> iterator() {
      return new FilterIterator<T>(type, MyList.this.iterator());
    }
  };
}

Nicole81 hat gesagt.:
zu 3. was genau macht das "super T" bei "Iterator<? super T>"?
Lässt einen Iterator zu, der mit T zuweisungskompatibel ist. Also einen der selbst mit genau Typ T oder einer super-Klasse (inkl. Object) oder einem super-Interface parametrisiert ist.

Nicole81 hat gesagt.:
wie schützt diese Implementierung vor Concurrent-Modification?
Indem sie dieses Thema einfach dem Original-Iterator überlässt. :cool:

[ edit ] Mehr zum Thema (API-Doc) ConcurrentModificationException.

Ebenius
 

Nicole81

Aktives Mitglied
Hab doch nochmal ein Problemchen:

Hab deine FilterIterator-Implementierung mal getestet, funktioniert soweit mit normaler Verwendung:

Code:
Iterator<Apfel> it = new FilterIterator<Apfel>(Apfel.class, fruechteListe.iterator());
while (it.hasNext())
{
    Apfel a = it.next();
    a.print();
}


In meine Früchteliste habe ich deine überschriebene Iterable mal eingefügt, bekomme aber eine StackOverflowException wenn ich das ganze so aufrufe:

Code:
for (Apfel a : fruechteListe.filteredIterable(Apfel.class))
{
    a.print();
}

Eine Idee woher das kommen könnte?

Tritt bei dieser Zeile auf:

Code:
    return new FilterIterator<T>(type, iterator());
 

Ebenius

Top Contributor
Nicole81 hat gesagt.:
Code:
    return new FilterIterator<T>(type, iterator());

Deswegen stand in meinem Beispiel (hier Zeile 6!):
Code:
public <T extends E> Iterable<T> filteredIterable(final Class<T> type) { 
  return new Iterable<T>() { 

    @Override 
    public Iterator<T> iterator() { 
      return new FilterIterator<T>(type, MyList.this.iterator()); 
    } 
  }; 
}

Ansonsten ruft sich die iterator()-Methode natürlich selbst auf. Du willst aber die iterator()-Methode der MyList benutzen. Klar?
 

Nicole81

Aktives Mitglied
hm lol so geht es, ich dachte das würde auf dasselbe rauskommen...

wärst du so nett mir den unterschied zu erklären bzw. was dieses Konstrukt "Klasse.this.methode()" generell ist, noch nie gesehen... :-(
 

Nicole81

Aktives Mitglied
ok klar denkfehler, so rufe ich ja die eigene "iterator"-Methode auf und nicht die der Listenklasse.... ok passt aber dass man das so aufruft.. ok wieder was gelernt, danke vielmals!!!

GuK
 

Ebenius

Top Contributor
Dieses new Iterable(){...}-Konstrukt ist eine nicht-statische, innere Klasse*. Das bedeutet, sie existiert im Kontext einer einschließenden Klasse (MyList). Wenn Du aus der inneren Klasse zum Beispiel get(7) aufrufen würdest, dann würde der Compiler
  1. zuerst in der Iterable(){...}-Klasse nachsehen,
  2. dort keine get()-Methode finden,
  3. dann in der äußeren Klasse nachsehen,
  4. dort die get()-Methode finden und diese dann verknüpfen.
Da wir aber nicht die get()-Methode aufrufen wollen, sondern die iterator()-Methode, findet der Compiler die nächste Methode, nämlich die aus der Iterable(){...}-Klasse und verknüpft diese. Mit dem Konstrukt "ÄussereKlasse.this" referenziert man die zugehörige this-Referenz der äußeren Klasse, damit der Compiler die Methode von da verknüpft und nicht aus der inneren Klasse.

Ist das Gestammel halbwegs verständlich? :)

* Außerdem eine anonyme Klasse, da sie keinen echten Namen hat; aber das spielt in dem Zusammenhang keine Rolle.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Bei dynamischer Arrayliste nach jeder Auswahl Zahl entfernen Java Basics - Anfänger-Themen 3
J Objekt-Array dynamischer Länge aus Benutzereingaben erstellen Java Basics - Anfänger-Themen 6
S Ein Bild mit dynamischer Quelle neuzeichnen Java Basics - Anfänger-Themen 12
O Statischer und Dynamischer Typ Java Basics - Anfänger-Themen 6
L Polymorphie Dynamischer oder Statischer Typ für Methodenparameter Java Basics - Anfänger-Themen 8
T Unterschied dynamischer und statischer Laufzeittyp Java Basics - Anfänger-Themen 1
W Dynamischer und statischer Typ von Referenzvariablen Java Basics - Anfänger-Themen 13
C Input/Output Dynamischer Output von Arrays Java Basics - Anfänger-Themen 3
D dynamischer Aufruf Java Basics - Anfänger-Themen 2
C Datentypen Array mit dynamischer Länge? Java Basics - Anfänger-Themen 14
J Verschachtelte for schleife mit dynamischer Anzahl an Schleifen Java Basics - Anfänger-Themen 10
G Dynamischer Methodenaufruf Java Basics - Anfänger-Themen 3
T Dynamischer JTabbedPane Probleme mit JTextArea Java Basics - Anfänger-Themen 2
G [Hibernate] Dynamischer Datenbankpfad Java Basics - Anfänger-Themen 4
S Fehler nach dynamischer Anpassung - Minesweeper Java Basics - Anfänger-Themen 6
V Dynamischer Klassen bzw. Methodenaufruf Java Basics - Anfänger-Themen 6
H statische, dynamischer Typ von Variablen Java Basics - Anfänger-Themen 1
B Dynamischer Filename Java Basics - Anfänger-Themen 3
M Variabler/dynamischer Objektname? Java Basics - Anfänger-Themen 12
M Java Iterator Verständnisfrage Java Basics - Anfänger-Themen 6
N Kann man einen Iterator nur einmal verwenden Java Basics - Anfänger-Themen 5
N Warum Springt iterator nur in der Schleife weiter Java Basics - Anfänger-Themen 9
volcanos HashSet und Iterator -> Falsche Sortierreihenfolge ? Java Basics - Anfänger-Themen 18
J Methoden Die Reihenfolge der Iterator-Elemente umkehren Java Basics - Anfänger-Themen 3
J Methoden iterator for-schleife (hasNext() ) Java Basics - Anfänger-Themen 7
Stargirlxo Iterator + Methode Java Basics - Anfänger-Themen 10
G Java Listen und Iterator Java Basics - Anfänger-Themen 2
U Hashmap Iterator selbst implementieren Java Basics - Anfänger-Themen 10
F nur das erste Element mit iterator ausgeben Java Basics - Anfänger-Themen 5
O Iterator erneut! Java Basics - Anfänger-Themen 8
O Iterator für eine geordnete Menge Java Basics - Anfänger-Themen 134
J Doppelte Ausgabe erzeugen Iterator Java Basics - Anfänger-Themen 6
K Iterator zurückliefern Java Basics - Anfänger-Themen 8
W Eigener Iterator soll mehrdimensionales Array durchlaufen Java Basics - Anfänger-Themen 4
S Iterator einer Liste Java Basics - Anfänger-Themen 4
B Sortieren mit Iterator Java Basics - Anfänger-Themen 4
I Erste Schritte Iterator Java Basics - Anfänger-Themen 3
M Iterator funktioniert nicht Java Basics - Anfänger-Themen 5
M Iterator cannot refer to a non final... Java Basics - Anfänger-Themen 20
O Interface Iterator Java Basics - Anfänger-Themen 2
M Collections Frage Beispielprogrammierung Iterator Java Basics - Anfänger-Themen 13
M Iterator Java Basics - Anfänger-Themen 25
J Iterator Funktioniert nicht richtig in StackImplementierung Java Basics - Anfänger-Themen 3
Z Hashmap Iterator löscht nicht Java Basics - Anfänger-Themen 8
L Iterator Java Basics - Anfänger-Themen 1
K Nutzung einer Klasse die das Iterator-Interface implementiert Java Basics - Anfänger-Themen 0
K Iterator-Interface implementieren mit Exception Handlung Java Basics - Anfänger-Themen 1
M Collections Iterator und generischer Baum Java Basics - Anfänger-Themen 0
O Kleine Frage zu Iterator und Iterable Java Basics - Anfänger-Themen 6
OnDemand Iterator Interfacve Java Basics - Anfänger-Themen 23
S Iterator next() Nullpointer Java Basics - Anfänger-Themen 2
T Methoden Iterator über ArrayList Java Basics - Anfänger-Themen 3
W Iterator Java Basics - Anfänger-Themen 2
D Aufgabe: Stack mit Iterator Java Basics - Anfänger-Themen 8
R Mit iterator auf Element zugreifen Java Basics - Anfänger-Themen 2
T Collections Zugriff auf Elemente aus Iterator() Schleife Java Basics - Anfänger-Themen 4
P Casting Warning bei Iterator Java Basics - Anfänger-Themen 32
F Wie Werte einer ArrayList an einen 'Custom'-Iterator übergeben? Java Basics - Anfänger-Themen 2
J Iterator Java Basics - Anfänger-Themen 5
P ArrayList mit Iterator / Iterable ausgeben Java Basics - Anfänger-Themen 8
B Funktionsweise Iterator unklar Java Basics - Anfänger-Themen 7
A Datentypen Iterator von hinten nach vorne durchlaufen Java Basics - Anfänger-Themen 4
D Wie Iterator Remove implementieren? Java Basics - Anfänger-Themen 11
B Datentypen Inhalt zum Iterator wieder aufrufen? Java Basics - Anfänger-Themen 10
D Iterator schaltet nicht weiter?! Java Basics - Anfänger-Themen 5
A Problem mit Iterator Java Basics - Anfänger-Themen 2
B Türme von Hanoi - Iterator Java Basics - Anfänger-Themen 50
V Hilfe beim implementieren von Iterator Java Basics - Anfänger-Themen 5
W Collections Iterator<E> Java Basics - Anfänger-Themen 7
L Lokale Variable und Instanzvariable innerhalb Iterator Java Basics - Anfänger-Themen 8
W OOP problem mit iterator! -.- Java Basics - Anfänger-Themen 9
B Iterator und Collection Java Basics - Anfänger-Themen 11
ruutaiokwu Iterator oder .size ??? Java Basics - Anfänger-Themen 6
vandread Iterator zählt nicht hoch?! Java Basics - Anfänger-Themen 3
L Problem mit Iterator bzw. Sortierte Liste Java Basics - Anfänger-Themen 14
N HashMap mit Iterator durchlaufen Java Basics - Anfänger-Themen 11
R Iterator Liste, Verständnisproblem Java Basics - Anfänger-Themen 4
J Verschachtelte for-Schleife mit Löschen von Iterationen. Wie über Iterator abbilden? Java Basics - Anfänger-Themen 6
M Iterator Java Basics - Anfänger-Themen 15
L Implementation gesucht - ArrayList.iterator() Java Basics - Anfänger-Themen 3
M Eigener Iterator für LinkedList Java Basics - Anfänger-Themen 20
pun Iterator über ArrayList Java Basics - Anfänger-Themen 12
P Iterator.add() Java Basics - Anfänger-Themen 3
A For Schleife - Iterator wird null Java Basics - Anfänger-Themen 7
? Map und iterator Java Basics - Anfänger-Themen 11
0x7F800000 ungereimtheiten mit Iterator/ListIterator Java Basics - Anfänger-Themen 2
J Iterator remove()? Java Basics - Anfänger-Themen 5
T Liste mit Iterator auslesen Java Basics - Anfänger-Themen 11
Kr0e Iterator Java Basics - Anfänger-Themen 2
D iterator instanziieren! Java Basics - Anfänger-Themen 11
M Der Umgang mit Iterator - Wie ein Objekt aus einer ArrayList Java Basics - Anfänger-Themen 2
J ArrayList mit Iterator Java Basics - Anfänger-Themen 3
W Iterator in Queue Java Basics - Anfänger-Themen 5
A Für was Iterator ? Java Basics - Anfänger-Themen 3
M warum interface iterator verwendbar? Java Basics - Anfänger-Themen 5
O Iterator - Durchlauf "einschränken" bzw. steuern&q Java Basics - Anfänger-Themen 2
K Collection und Iterator Java Basics - Anfänger-Themen 7
Q Iterator next erstellen Java Basics - Anfänger-Themen 4
S iterator problem Java Basics - Anfänger-Themen 3
S Iterator --__-- Zugriff auf nächstes Element Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben