Java 将HashMap迭代器强制转换为具体类型时的ClassCastException

Java 将HashMap迭代器强制转换为具体类型时的ClassCastException,java,iterator,hashmap,processing,Java,Iterator,Hashmap,Processing,我对processing.org和Java非常陌生。我试图将对象存储在HashMap中,然后迭代HashMap的值,调用存储对象上的方法。 为了做到这一点,我假设需要将迭代器向下转换为我的类的类型,但这会抛出一个ClassCastException(“java.util.HashMap$ValueIterator不能转换为sketch_oct27a$MyClass”)。以下简化代码演示了此行为: import java.util.*; void setup() { HashMap m =

我对processing.org和Java非常陌生。我试图将对象存储在HashMap中,然后迭代HashMap的值,调用存储对象上的方法。 为了做到这一点,我假设需要将迭代器向下转换为我的类的类型,但这会抛出一个ClassCastException(“java.util.HashMap$ValueIterator不能转换为sketch_oct27a$MyClass”)。以下简化代码演示了此行为:

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

如何通过迭代器调用SaySomething()方法?

这是使用迭代器的方式:

((MyClass)iter.next()).SaySomething();
更好的方法是使用泛型,这样您就不必强制转换:

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

您的代码当前执行以下操作:

    ((MyClass)iter).SaySomething();
这表示“cast
iter
作为
MyClass
的实例,并调用其
SaySomething()
方法。这失败了,因为
iter
实例的实际类将是实现接口
java.util.Iterator
的某个内部类。该类将不是MyClass的子类

您需要做的是让迭代器传递其下一个值,并转换该值;即

    ((MyClass) (iter.next())).SaySomething();
您可以将其简化为:

    ((MyClass) iter.next()).SaySomething();
因为Java操作符的优先级

@Michael指出,如果使用泛型,就可以摆脱明显的类型转换。通过使用Java 5.0中引入的“新”for循环语法,可以进一步简化:

    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(); 
    }
HashMap m=newhashmap();
m、 put(“First”,new MyClass());
m、 放置(“第二个”,新的MyClass());
m、 放置(“第三个”,新MyClass());
对于(MyClass mc:m.values()){
mc.saything();
}
事实上,for循环只是语法上的糖分。在幕后,迭代器实例是按照您的代码创建和使用的(经过更正)。即使是类型转换也在执行中……除非JIT能够发现它可以优化它


编辑:如果你不能使用Java 1.5,那么你只能用老式的方式来做。听起来“processing.org”需要让他们一起行动。Java 1.4.x平台真的过时了。

或posh for循环:
for(MyClass value:map.values()){m.saySomething();}
非常感谢您的快速响应——我的问题现在已经解决了。另外,processing.org不做泛型,因为它仅限于Java 1.4(即使用PDE时)。
    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(); 
    }