【问题标题】:Java Iterating Over a TreeMap - incompatible typesJava 迭代 TreeMap - 不兼容的类型
【发布时间】:2014-01-30 02:30:24
【问题描述】:

我有以下收藏:

private Map <String, Staff> staff;

实现为 TreeMap:

staff = new TreeMap <String, Staff> ();

我需要遍历此映射中的值,但是当我尝试以下代码时,我遇到了不兼容的类型编译错误。我不明白为什么会这样;我地图中的值是 Staff 对象和

it.HasNext() 

应该将它们返回以存储在 staffMember 变量中,据我所知,这应该没问题?非常感谢帮助。

Collection <Staff> staffList = staff.values(); 
         Iterator it = staffList.iterator ();
         while ((isJobAssigned = false) ||it.hasNext())
         {
             Staff staffMember = it.next(); 
             if ((staffMember instanceof Typist) && (jobType.equalsIgnoreCase("Typist")))
             {
                 newJob.setJobState ("Assigned");
                 staffMember.setState("Working");
                 return newJon.getJobNo() + " Staff allocated: " + staffMember.getName () + ", ID: " + staffMember.getId();
                }

【问题讨论】:

  • 使用instanceof 是代码味道的标志。考虑在枚举上有一个enum 的工作人员类型和一个大小写开关。 Staff 类可以有一个 abstract 方法来强制任何实现返回其类型。更好的解决方案是访问者模式。
  • 谢谢,我已经读过几遍关于 instanceof 的滥用以及它是一种糟糕的代码气味的事实,因此将在未来的项目中避免并按照您的建议进行重构。

标签: java iterator iteration treemap


【解决方案1】:

您使用的是原始Iterator。您需要将it.next() 返回的Object 转换为Staff,或者使用通用的Iterator

使用原始迭代器:

Staff staffMember = (Staff)it.next(); 

使用通用迭代器(我推荐这个版本):

Iterator<Staff> it = staffList.iterator();
Staff staffMember = it.next();  //you can keep this

【讨论】:

  • 如果可以指定类型,请不要使用原始迭代器,确保类型安全。 +1
  • 谢谢,我实施了您推荐的解决方案,并且效果很好。我将对泛型进行一些研究,以确保我完全理解这一点。再次感谢。
【解决方案2】:

你为什么不使用:

for (Staff st : staff.values()){
 // do your stuff
 if(st instanceof Typist) break;   
}

【讨论】:

  • 虽然没有回答问题,但绝对是更好的解决方案。
  • 我想在我们到达与工作类型匹配的第一个员工时停止迭代,所以我认为使用 while 循环会更好?
  • 为什么不打破?我使用从您的问题复制的条件编辑了我的答案,但这里的一般要点是使用 break 退出循环。
  • 因为我是新手 :-) 现在你已经解释过了,这是一个很好的观点。我只是坚持 FOR = 遍历整个集合,WHILE = 无限迭代的硬性规则。不过,这是一种巧妙的技术,而且肯定会整理这段代码。
猜你喜欢
  • 2015-07-03
  • 2020-05-20
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多