0

我对 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() 方法?

4

2 回答 2

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();
}
于 2009-10-26T22:48:35.913 回答
2

您的代码当前执行此操作:

    ((MyClass)iter).SaySomething();

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

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

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

实际上,for 循环只是语法糖。在幕后, Iterator 实例正在根据您的代码创建和使用(带有更正)。甚至正在执行类型转换......除非 JIT 可以弄清楚它可以优化它。

编辑:如果你不能使用 Java 1.5,那么你就只能用老式的方式来做这件事了。听起来像“processing.org”需要一起行动。Java 1.4.x 平台确实已经过时了。

于 2009-10-26T23:11:47.700 回答