Frage

Ich bin sehr neu für Processing.org und Java. Ich versuche, Objekte in einer HashMap zu speichern und dann die Werte der HashMap iterieren, Methoden auf die gespeicherten Objekte aufrufen. Um das zu tun, ich nehme an, ich brauche den Iterator auf die Art meiner Klasse niedergeschlagenen, aber das wirft einen Classcast ( „java.util.HashMap $ ValueIterator kann nicht auf sketch_oct27a $ MyClass gegossen werden“). Der folgende vereinfachten Code demonstriert dieses Verhalten:

import java.util.*;

void setup() {
  HashMap m = new HashMap();

  m.put("First", new MyClass());
  m.put("Second", new MyClass());
  m.put("Third", new MyClass());

  Iterator iter = m.values().iterator();

  while (iter.hasNext()) {
   ((MyClass)iter).SaySomething(); // Throws ClassCastException
   iter.next();
  }    
}

class MyClass { 
  void SaySomething() {
    println("Something");
  }
}

Wie kann ich den SaySomething () -Methode durch den Iterator nennen?

War es hilfreich?

Lösung

Dies ist, wie man einen Iterator verwenden:

((MyClass)iter.next()).SaySomething();

Noch besser wäre es, verwenden Generics so dass Sie sich überhaupt nicht werfen:

HashMap<MyClass> m = new HashMap<MyClass>();
...
Iterator<MyClass> iter = m.values().iterator();
...
iter.next().SaySomething();

Sie können dann sogar den Iterator ganz überspringen (eigentlich diese Syntax nur versteckt es, es noch implizit verwendet wird):

for(MyClass element : m.values())
{
    element.SaySomething();
}

Andere Tipps

Ihr Code zur Zeit tut dies:

    ((MyClass)iter).SaySomething();

Das sagt „cast iter als Instanz von MyClass und seine SaySomething() Methode aufrufen. Dies schlägt fehl, da die tatsächliche Klasse der iter Instanz einige innere Klasse sein, die die Schnittstelle java.util.Iterator implementiert. Diese Klasse wird nicht eine Unterklasse von MyClass sein.

Was Sie tun müssen, ist den Iterator zu bekommen, um seinen nächsten Wert zu liefern, und diesen Wert werfen; d.

    ((MyClass) (iter.next())).SaySomething();

, die Sie können vereinfachen:

    ((MyClass) iter.next()).SaySomething();

wegen Java Operator Vorrang.

@ Michael weist darauf hin, dass, wenn Sie Generika verwenden Sie loszuwerden, die offene Typumwandlung bekommen.

: Sie können mit dem „neuen“ for-Schleife Syntax eingeführt in Java 5.0 noch weiter vereinfachen
    HashMap<String, MyClass> m = new HashMap<String, MyClass>();

    m.put("First", new MyClass());
    m.put("Second", new MyClass());
    m.put("Third", new MyClass());

    for (MyClass mc : m.values()) {
        mc.SaySomething(); 
    }

In Wirklichkeit ist der for-Schleife ist nur syntaktischer Zucker. Unter den Abdeckungen wird die Iterator-Instanz wird nach Ihrem Code (mit Korrektur) erstellt und verwendet. Auch die Typumwandlung durchgeführt wird ... es sei denn, der JIT herausfinden, dass sie es weg optimieren können.

EDIT: Wenn Sie nicht mehr als 1,5 Java verwenden können, dann sind Sie mit tun dies die altmodische Art und Weise fest. Klingt wie „processing.org“ zusammen, um ihre Tat bekommen muss. Die Java 1.4.x-Plattform ist wirklich veraltet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top