Iterator Frage die Zweite
-
lettort schrieb:
Ein Iterator ist doch ein Objekt, welches einen Containerinhalt schrittweise wiedergeben kann. Wenn dieses Objekt also einen Inhalt besitzt, dann wäre es doch sinnig, dass es über sein eigenes Ende bescheid weiss.
ja, und?
Es waere auch "sinnig" dass ein Vogel eine "flieg()" methode hat, oder?
Aber die Erfahrung hat gezeigt, dass n Pinguin und ein Strauss Voegel sind die nicht fliegen koennen.Ist es jetzt un-oo wenn ich Behaviors einbaue?
Es kann ja nicht im OO-Kontext sein, dass ein Aussenseiter sich noch Gedanken darüber machen muss, dass er ein Ende "überfährt".
Warum?
Das sind ploetzlich 2 verantwortungen in einem Objekt:
- ist es ein iterator im C++ sinne - also ein "zeiger" auf den inhalt der Collection
und - ist es ploetzlich eine iteratoren-range.
Ist das nicht genauso eine Schwachstelle wie dass man in c++ immer ein iteratoren paar braucht?
Was ist jetzt besser? Was ist mehr OO?
Ist es nicht einfach so, dass es 2 Loesungen fuer 1 Problem sind?
Dass Iterator in Java eher ein IteratorRange ist? Ein high level konzept. und das iteratoren konzept in C++ eher low leveliger?
OT:
wenn dir soviel daran liegt dass iteratoren eine range sein sollen, dann mach doch eine iterator_range klasse die ein iteratore paerchen nimmt und deine .next und so methoden anbietet.
- ist es ein iterator im C++ sinne - also ein "zeiger" auf den inhalt der Collection
-
Ein Iterator ist doch ein Objekt, welches einen Containerinhalt schrittweise wiedergeben kann. Wenn dieses Objekt also einen Inhalt besitzt, dann wäre es doch sinnig, dass es über sein eigenes Ende bescheid weiss.
Nein, ein Iterator ist nur ein Pointer (wenn auch ein schlauer). Er zeigt nur wo etwas im Container drin liegt, er selbst hat kein Inhalt aus dem Container.
-
Artchi schrieb:
Ein Iterator ist doch ein Objekt, welches einen Containerinhalt schrittweise wiedergeben kann. Wenn dieses Objekt also einen Inhalt besitzt, dann wäre es doch sinnig, dass es über sein eigenes Ende bescheid weiss.
Nein, ein Iterator ist nur ein Pointer (wenn auch ein schlauer). Er zeigt nur wo etwas im Container drin liegt, er selbst hat kein Inhalt aus dem Container.
Stimmt, ist auch in Java so. Nur weis der Iterator in Java wo er sich grade befindet (im Container).
Aber Shade Of Mine hat soweit Recht, es sind einfach nur 2 Lösungen für das selbe Problem.
@RHBaum:
Eine Map<K, V> hatpublic Set<Map.Entry<K,V>> entrySet();Der Set hat dann einen Iterator<Map.Entry<K,V>>.
BTW: Gibt's in Java auch bidirectionale oder Random-Access-Iteratoren ? Immerhin kann ich mich in C++ auch mittels "--it" oder "it += 3" über eine Liste bewegen ... da ist ein "hasNext()" wenig hilfreich.
In Java ist halt ein anderes Container-Konzept als in der STL.
Für it+=3 kannst du gleich vector.get(i*3) verwenden, RandomAccess ist sowieso nur bei Vectors sinnvoll, weniger bei Listen.
Für --it hast du den ListIterator<E>, mit hasPrevious() und previous().
-
lettort schrieb:
Dann brauche ich ja trotzdem 2 Iteratoren - begin und end. Einem zum Starten der dann gegen den Zweiten läuft.
Wo ist dann bitte der Sinn dahinter? Kann dann auch gleich in einer Schleife direkt aus dem Vector mir die Werte geben lassen und ständig überprüfen ob Vector::size() erreicht ist.
Für die Lösung mit dem Iteratoren-Paar begin/end gibt es zwei Gründe.
1.) Mit dem Iteratoren-Paar kann man nicht nur vom aktuellen Stand bis zum Ende eines Containers laufen sondern über ein beliebiges (halboffenes) Intervall [a,b). Also wenn ein Iteratoren-Paar a,b vorliegt, wobei b von a aus durch eine endliche Folge von Inkrementierungen erreichbar ist, kann man diese als Input für z.B. einen Algorithmus benutzen.
2.) In C++ sollen Iteratoren mit Pointern kompatibel sein. Da man einem Pointer nicht ansehen kann, ob er auf das Ende eines Containers zeigt, hat man die Lösung mit dem Vergleich auf end gewählt.Gruß
Werner
-
@Werner Salomon:
3) Ein Output-Iterator braucht z.B. garkeine Ende/Limit zu haben.@all:
Ich würde die Iteratoren von Java eher "Enumerator" nennen statt Iterator. Dann riecht es auch gleich weniger nach Vermischung von Aufgaben.@lettort:
Um was gehts jetzt eigentlich noch? Dass diese Sache in der C++ Standard-Lib anders gelöst wurde als in der Java Standard-Lib wissen nun ja alle. Dass C++ Iteratoren bis auf die zwei Sonderfälle "will nur ein Objekt übergeben" und "will Objekt aus der Collection entfernen ohne zu wissen wo die Collection ist" mächtiger sind sollte auch klar sein (*hust*, *duck*). Dafür halt auch komplizierter.C++ ist eben nicht Java, und Java ist nicht der Weisheit letzter Schluss. Wenn du mich fragst ist Java zwar näher an einer wirklich brauchbaren Sprache für grosse Projekte (die nicht unbedingt Hardwarenahe oder Realtime sein müssen), aber es gibt doch einige Dinge die doof sind. Gerade in der Standard-Lib.
Es hindert dich aber niemand daran für deine Projekte einen (relativ) einfachen Adapter zu schreiben (z.B. Template<DatenTyp> Klasse mit Template<IteratorTyp> Konstruktor) der a) unabhängig vom Container-Typ verwendbar ist und b) eine "hasNext" Funktion implementiert. Wenn du das in einem C++ Projekt machst wo noch andere C++ Programmierer mitarbeiten mach dich aber schonmal darauf gefasst u.U. einige Hate-Mails zu bekommen

-
Plotzenhotz schrieb:
"will Objekt aus der Collection entfernen ohne zu wissen wo die Collection ist"
*hust* UnsupportedOperationException *hust*
-
Ja, das kommt noch dazu, UnsupportedOperationException statt grosser/tiefer Interface-Hierarchien ist halt typisch Java-Style (tm) *hust-hust*.

Aber was Programmierfehler angeht die man erst zur Laufzeit merkt ... das kann C++ auch sehr gut *hüstel*.
-
Plotzenhotz schrieb:
Aber was Programmierfehler angeht die man erst zur Laufzeit merkt ... das kann C++ auch sehr gut *hüstel*.
Ne, ne. Da verstehst du was falsch.
Die Programmierfehler findet man in C++ nicht zur "Laufzeit" sondern zur "nachdem-die-software-verkauft-wurde"-Zeit

-
Hihi, ja, das auch. @OP: Sorry wegen OT im übrigen.
-
DEvent schrieb:
...In Java ist halt ein anderes Container-Konzept als in der STL.
Für it+=3 kannst du gleich vector.get(i*3) verwenden, RandomAccess ist sowieso nur bei Vectors sinnvoll, weniger bei Listen.
Für --it hast du den ListIterator<E>, mit hasPrevious() und previous().
Danke für die Info !!
Gruß,
Simon2.
-
Plotzenhotz schrieb:
...Aber was Programmierfehler angeht die man erst zur Laufzeit merkt ... das kann C++ auch sehr gut *hüstel*.
Dafür kann man on C++ aber Vieles schon zur Compilezeit rausfinden.

(im Konrekten Beispiel bin ich einfach froh, wenn mir der Compiler oftmals schon beim Füllen des Containers sagen kann, dass mein Objekt da nicht reingehört).
Aber nach einer positiv kontroversen Java-Seminar, bin ich kein unversönlicher Java-Ablehner und C++-Befürworter mehr.
Gruß,
Simon2.
-
Dass C++ Iteratoren [...] mächtiger sind sollte auch klar sein (*hust*, *duck*). Dafür halt auch komplizierter.
Wo sind jetzt C++ Iteratoren mächtiger?
-
DEvent schrieb:
Dass C++ Iteratoren [...] mächtiger sind sollte auch klar sein (*hust*, *duck*). Dafür halt auch komplizierter.
Wo sind jetzt C++ Iteratoren mächtiger?
flexibler trifft es besser.
Sie sind naemlich auf einem niedrigeren Level abstrahiert als die Java-Iteratoren.
Enumerator beschreibt nen Java Iteratoren besser. Aber das alter Enumerator Interface war nicht wirklich so der Hammer - deshalb ist Java davon abgefallen und hat ein besseres Konzept gemacht.
Es ist ein ziemlicher High Level Ansatz an das Iteratore Pattern, waehrend man in C++ ziemlich direkt sagt: ein iteratore ist ein Zeiger in einer Collection.
In Java muesste man sagen: ein Iterator ist ein Enumerator einer Range in einer Collection.
Ein Java-Iteratore macht deshalb mehr als ein C++ iterator, aber das raubt halt flexibilitaet. Java Iteratoren sind fuer das iterieren ueber die komplette Collection optimiert, waehrend C++ iteratoren auf flexibilitaet getrimmt sind.