Pergunta

Eu sou muito novo para processing.org e Java. Eu estou tentando armazenar objetos em um HashMap, e depois repetir os valores do HashMap, chamando métodos nos objetos armazenados. A fim de fazer isso, presumo eu preciso para downcast o iterador para o tipo de minha classe, mas isto lança uma ClassCastException ( "java.util.HashMap $ ValueIterator não pode ser convertido para sketch_oct27a $ MyClass"). O código simplificado a seguir demonstra esse 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");
  }
}

Como faço para chamar o método SaySomething () através do iterador?

Foi útil?

Solução

Esta é a forma como você usa um iterador:

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

Melhor ainda, usar os genéricos para que você não tem que elenco em tudo:

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

Você pode então mesmo pular o iterador inteiramente (na verdade, esta sintaxe apenas esconde-lo, ele ainda é usado implicitamente):

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

Outras dicas

Seu código atualmente faz isso:

    ((MyClass)iter).SaySomething();

Este diz "iter elenco como uma instância de MyClass e chamar seu método SaySomething(). Esta falha porque a classe real da instância iter serão alguns classe interna que implementa a interface java.util.Iterator. Essa classe não será uma subclasse de MyClass.

O que você precisa fazer é obter o iterador para entregar seu próximo valor e elenco que valor; i.

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

que você pode simplificar a:

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

por causa do Java precedência do operador.

@ Michael assinala que se você usar os genéricos você pode se livrar do typecast evidente. Você pode simplificar ainda mais usando o "novo" para a sintaxe de loop introduzido em 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(); 
    }

Na realidade, o loop é apenas açúcar sintático. Debaixo das cobertas, a instância Iterator está sendo criado e usado de acordo com o seu código (com a correção). Mesmo o tipo elenco está sendo realizado ... a menos que o JIT pode descobrir que ele pode otimizar-lo.

EDIT: se você não pode usar Java 1.5, então você está preso com isso da maneira old-fashioned. Soa como necessidades "processing.org" para obter a sua juntos ato. A plataforma Java 1.4.x é realmente fora da data.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top