我对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()方法?
答案 0 :(得分:6)
这是你使用迭代器的方法:
((MyClass)iter.next()).SaySomething();
更好的是,使用泛型,以便你根本不需要施放:
HashMap<MyClass> m = new HashMap<MyClass>();
...
Iterator<MyClass> iter = m.values().iterator();
...
iter.next().SaySomething();
然后你甚至可以完全跳过迭代器(实际上,这个语法只是隐藏它,它仍然是隐式使用的):
for(MyClass element : m.values())
{
element.SaySomething();
}
答案 1 :(得分:2)
您的代码目前正在执行此操作:
((MyClass)iter).SaySomething();
这表示“将iter
作为MyClass
的实例并调用其SaySomething()
方法。这会失败,因为iter
实例的实际类将是某个内部类实现接口java.util.Iterator
。该类不是MyClass的子类。
您需要做的是让迭代器提供下一个值,然后转换该值;即。
((MyClass) (iter.next())).SaySomething();
你可以简化为:
((MyClass) iter.next()).SaySomething();
因为Java运算符优先。
@Michael指出,如果你使用泛型,你可以摆脱公开的类型转换。您可以使用Java 5.0中引入的“new”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();
}
实际上,for循环只是语法糖。在封面下,正在创建Iterator实例并根据您的代码使用(带有更正)。即使是正在执行的类型转换......除非JIT能够发现它可以优化它。
编辑:如果你不能使用Java 1.5那么你就会坚持用老式的方式做这件事。听起来像“processing.org”需要一起行动。 Java 1.4.x平台真的已经过时了。