【问题标题】:ClassCastException When Casting HashMap Iterator to a Concrete Type将 HashMap 迭代器转换为具体类型时发生 ClassCastException
【发布时间】:2009-10-26 22:46:47
【问题描述】:

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

【问题讨论】:

    标签: java iterator hashmap processing


    【解决方案1】:

    这是你使用迭代器的方式:

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

    【讨论】:

    • 或者豪华的 for 循环:for (MyClass value : map.values()) { m.saySomething(); }
    • 非常感谢您的快速响应——我的问题现已解决。附带说明一下,processing.org 不做泛型,因为它仅限于 Java 1.4(即使用 PDE 时)。
    【解决方案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 中引入的“新”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 平台真的已经过时了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2019-10-23
      相关资源
      最近更新 更多