Domanda

Sono molto nuovo su processing.org e Java. Sto cercando di archiviare oggetti in una HashMap e quindi scorrere i valori di HashMap, chiamando i metodi sugli oggetti memorizzati. Per fare ciò, suppongo di dover eseguire il downgrade dell'iteratore al tipo della mia classe, ma ciò genera una ClassCastException (" java.util.HashMap $ ValueIterator non può essere trasmesso a sketch_oct27a $ MyClass "). Il seguente codice semplificato dimostra questo comportamento:

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

Come posso chiamare il metodo SaySomething () tramite l'iteratore?

È stato utile?

Soluzione

Ecco come si usa un iteratore:

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

Meglio ancora, usa Generics in modo da non dover assolutamente lanciare:

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

Puoi anche saltare completamente l'iteratore (in realtà, questa sintassi lo nasconde, è ancora usato implicitamente):

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

Altri suggerimenti

Il tuo codice attualmente lo fa:

    ((MyClass)iter).SaySomething();

Questo dice " cast iter come un'istanza di MyClass e chiama il suo metodo SaySomething () . Ciò non riesce perché la classe effettiva dell'istanza iter sarà una classe interna che implementa l'interfaccia java.util.Iterator . Quella classe non sarà una sottoclasse di MyClass.

Quello che devi fare è far sì che l'iteratore fornisca il suo prossimo valore e lanci quel valore; cioè.

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

che puoi semplificare a:

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

a causa della precedenza dell'operatore Java.

@Michael sottolinea che se usi i generici puoi sbarazzarti del typecast manifesto. Puoi semplificare ulteriormente utilizzando il "nuovo" nuovo per la sintassi del loop introdotta in 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(); 
    }

In realtà, il ciclo for è solo zucchero sintattico. Sotto le copertine, l'istanza di Iterator viene creata e utilizzata secondo il tuo codice (con la correzione). Anche il cast di tipo viene eseguito ... a meno che la JIT non riesca a capire che può ottimizzarlo via.

EDIT: se non puoi usare Java 1.5, allora sei bloccato nel farlo alla vecchia maniera. Sembra " processing.org " ha bisogno di mettere insieme i loro atti. La piattaforma Java 1.4.x è davvero obsoleta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top