Java Java Casting Inkonsistenz Frage

Helios co.

Lt. Commander
Registriert
März 2005
Beiträge
1.863
Hallo @all,

mir ist etwas komisches aufgefallen, dass ich mir nicht logisch erklären kann. Folgende Situation:

Ich definiere einen Vektor der Art:
Code:
Vector<Double> summeMaxSim = new Vector<Double>()

Nun möchte ich Werte aus dem Vektor holen und in einer Variable vom Typ Double aufsummieren:
Code:
double summe = 0;
Iterator itt = summeMaxSim.iterator();
while(itt.hasNext()){
	summe += [B](Double)[/B]itt.next();
}

Wieso muss ich an der Stelle itt.next() die Ergebnisse auf Double casten? Schließlich dürfte klar sein, dass die Werte im Vektor vom Typ Double sind?
 
Dir ist das natürlich klar, dass dort ein Double drin sein muss weil du den Iterator über einen Vector<Double> iterieren lässt.

Für Java (bzw. deinen Iterator) ist das aber garnicht klar. Dein Iterator soll ja nur über irgendeine Datenstruktur iterieren (Liste, Vector, ...) und dem ist es völlig egal was an den einzelnen Stellen deines Vektors liegt, er soll ja nur drüber iterieren und dir den Zugriff auf die Elemente ermöglichen. Iterator.next() gibt dir nun ein Element aus deinem Vektor, liefert aber einen generischen Datentyp zurück (es könnte ja alles mögliche in deinem Vektor stecken), daher musst du den erstmal casten damit klar ist welcher Datentyp nun drin war.
 
wenn du dem Iterator deinen Objekttyp mitteilst, entfällt das Casten:
Code:
double summe = 0;
[B]Iterator<Double>[/B] itt = summeMaxSim.iterator();
while(itt.hasNext()){
	summe += itt.next();
}
Java ist da leider etwas veraltet.
 
Hat diese Form des Iterators einen Vorteil gegenüber:
Code:
        Vector<Double> summeMaxSim = new Vector<Double>();
        
        double summe = 0;
        
        for (Double d : summeMaxSim)
        {
            summe += d;
        }
?

Wenn nicht, wüsste ich nicht, warum man sich noch damit rumplagen sollte.
 
nein, hat sie nicht.
die erweiterte For-Schleife macht das gleiche wie die Iterator-Version, ist eben syntactic sugar.
Guter Einwand ;)
 
wenn du dem Iterator deinen Objekttyp mitteilst, entfällt das Casten:

Das ist mir auch so weit eingeleuchtet, aber jetzt wundere ich mich im Grunde nur noch, wozu man den Objekttyp bei den Collections, hier Vector, überhaupt setzen muss.
Letztenendes reicht es doch diesen beim Iterator anzugeben und man hat es leichter wenn man später damit arbeiten will.

Höchstens um irgendwelche Konsistenzprpobleme beim Programmieren direkt zu erkennen. Sonst scheint mir dieses Feature komplett sinnlos.

Als syntactic sugar empfinde ich diese Schreibeweise eigentlich nicht:
Code:
for (Double d : summeMaxSim)
        {
            summe += d;
        }
das ist eher der Anfang vom Ende einer sonst sehr guten Sprache.
 
Was genau gefällt dir an der Java-Foreach-Schleife nicht?
Ich selbst mag sie recht gerne. Vorallem immer dann, wenn ich über was itterieren will, was keinen Iterator hat und wo es nicht wichtig ist, wo welches Element steht.
 
Helios co. schrieb:
Das ist mir auch so weit eingeleuchtet, aber jetzt wundere ich mich im Grunde nur noch, wozu man den Objekttyp bei den Collections, hier Vector, überhaupt setzen muss.
Letztenendes reicht es doch diesen beim Iterator anzugeben und man hat es leichter wenn man später damit arbeiten will.

Höchstens um irgendwelche Konsistenzprpobleme beim Programmieren direkt zu erkennen. Sonst scheint mir dieses Feature komplett sinnlos.
du kannst dem Iterator keinen Objecttyp geben, wenn die Collction keinen hatte ;)
Hat etwas mit der Generizität zu tun, ist aber ein sehr komplexes Thema.

Helios co. schrieb:
Als syntactic sugar empfinde ich diese Schreibeweise eigentlich nicht: [...]
das ist eher der Anfang vom Ende einer sonst sehr guten Sprache.

die Schleife ist aussagekräftiger ;)
In weniger Code macht sie genau das gleiche wofür man sonst mehr Zeilen braucht.
 
@Helios co.
Aus gegebenem Anlass mit der For-Each-Schleife und den Generics kann ich dir (und vielen anderen Java-Entwicklern) nur dieses Buch wärmstens empfehlen. Bin leider noch nicht durch, aber das, was ich bisher gelesen habe, war äußerst interessant. Eine For-Each-Schleife lässt sich nicht nur einfacher lesen bzw. ist kürzer, sondern auch performanter. Darüber hinaus wird auf die korrekte Behandlung von Generics eingegangen und und und.
Man bekommt Step by Step erklärt, warum das eine dem anderen vorzuziehen ist oder für welche Einsatzzwecke sich besondere Klassen und Methoden anbieten.
 
Die for-each-Schleife hat auch noch den Vorteil, dass man sich nicht immer um die Verschiebung des Zeigers (Erhöhen des Schleifenzählers, ...) kümmern muss...
Ebenfalls vermindert es das off-by-one-Risiko wie
Code:
  for (int i = 0; i <= array.length; i++) {
Und hier hat man an drei Stellen das i und dann noch in der Schleife... die Iteratoren sind da auch nicht wirklich übersichtlicher..
 
skillless schrieb:
Eine For-Each-Schleife lässt sich nicht nur einfacher lesen bzw. ist kürzer, sondern auch performanter.

Stimmt nicht generell. Zum Iterieren über Random-Access-Listen ist die herkömmliche Methode schneller:

List<String> strings = new ArrayList<String>();
...
for (int i = 0, size = strings.size(); i < size; i++) {
...
}
 
>Stimmt nicht generell. Zum Iterieren über Random-Access-Listen ist die herkömmliche Methode schneller:

Das erläuter bitte etwas näher. Da bin ich mal gespannt.
 
Es fällt ein minimaler Overhead an, was soares andeutet.
Allerdings vergisst er, dass der direkte index-Zugriff nur schneller ist, wenn die List-Implementierung (wie bei ArrayList) wahlfreien Zugriff erlaubt, mit einer LinkedList hingegen wird die Performance absolut miserabel sein.
Da Collections in Java als Typ unter ihrem Interface gespeichert werden sollten (Implementierung gegen eine Schnittstelle und nicht konkrete Implementation), wäre ich also sehr vorsichtig über den Index zuzugreifen.
 
Ein weiterer nicht ganz uninteressanter Unterschied ist
Iterators are fail fast - any operation that structurally modifies the underlying collection( such as remove() ) will immediately have an affect on the iterator. However, looping over an index can have potential invalid references or skip elements if you remove() elements.
source
 
Naja, die Collection, über die man gerade iterieren möchte, innerhalb der Schleife zu modifizieren, ist eh unklug und sollte daher vermieden werden.
 
ice-breaker schrieb:
Allerdings vergisst er, dass der direkte index-Zugriff nur schneller ist, wenn die List-Implementierung (wie bei ArrayList) wahlfreien Zugriff erlaubt, mit einer LinkedList hingegen wird die Performance absolut miserabel sein.

Ich schrieb doch explizit, dass diese Schleife nur mit Random-Access-Listen schneller ist! Gibt extra ein Marker-Interface dafür, mit dem sich das testen lässt, falls man irgendwo eine entsprechende Optimierung vornehmen möchte.
 
CoolHandLuke schrieb:
Naja, die Collection, über die man gerade iterieren möchte, innerhalb der Schleife zu modifizieren, ist eh unklug und sollte daher vermieden werden.

Könnte ja auch von einem anderen Thread aus passieren.
 
Die Möglichkeit in einer Schleife die Collection zu verändern ist in bestimmten Fällen sinnvoll und genau dafür ist dann der Iterator gut.

while (i.hasNext()){
Object o = i.next();
if (!isValid(o))
i.remove();
}

Mal als kleines Pseudocode-Beispiel.
 
Zurück
Oben