Pregunta

Soy muy nuevo en processing.org y Java. Estoy tratando de almacenar objetos en un HashMap y luego iterar sobre los valores de HashMap, llamando a los métodos en los objetos almacenados. Para hacer eso, supongo que necesito bajar el iterador al tipo de mi clase, pero esto arroja una ClassCastException (" java.util.HashMap $ ValueIterator no se puede convertir en sketch_oct27a $ MyClass "). El siguiente código simplificado demuestra este comportamiento:

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");
  }
}

¿Cómo llamo al método SaySomething () a través del iterador?

¿Fue útil?

Solución

Así es como usas un iterador:

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

Mejor aún, use Generics para no tener que lanzar nada:

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

Incluso puede omitir el iterador por completo (en realidad, esta sintaxis simplemente lo oculta, todavía se usa implícitamente):

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

Otros consejos

Su código actualmente hace esto:

    ((MyClass)iter).SaySomething();

Esto dice " cast iter como una instancia de MyClass y llama a su método SaySomething () . Esto falla porque la clase real de la instancia de iter será alguna clase interna que implementa la interfaz java.util.Iterator . Esa clase no será una subclase de MyClass.

Lo que debe hacer es hacer que el iterador entregue su próximo valor y emitir ese valor; es decir

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

que puede simplificar a:

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

debido a la precedencia del operador Java.

@Michael señala que si usas genéricos puedes deshacerte de la escritura abierta. Puede simplificar aún más utilizando el " nuevo " para la sintaxis de bucle introducida en Java 5.0:

    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(); 
    }

En realidad, el ciclo for es solo azúcar sintáctico. Debajo de las cubiertas, la instancia de Iterator se está creando y utilizando según su código (con la corrección). Incluso el tipo de conversión se está realizando ... a menos que el JIT pueda darse cuenta de que puede optimizarlo.

EDITAR: si no puede usar Java 1.5, entonces no puede hacerlo de la manera tradicional. Suena como " processing.org " necesita actuar juntos. La plataforma Java 1.4.x está realmente desactualizada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top