遍历 hastable 键的枚举会引发 NoSuchElementException 错误

Posted

技术标签:

【中文标题】遍历 hastable 键的枚举会引发 NoSuchElementException 错误【英文标题】:iterating through Enumeration of hastable keys throws NoSuchElementException error 【发布时间】:2011-11-01 21:35:05 【问题描述】:

我正在尝试使用枚举从哈希表中迭代一个键列表,但是我在列表中的最后一个键处不断收到 NoSuchElementException?

Hashtable<String, String> vars = new Hashtable<String, String>();

vars.put("POSTCODE","TU1 3ZU");
vars.put("EMAIL","job.blogs@lumesse.com");
vars.put("DOB","02 Mar 1983");

Enumeration<String> e = vars.keys();

while(e.hasMoreElements())

System.out.println(e.nextElement());
String param = (String) e.nextElement();

控制台输出:

电子邮件 邮政编码 线程“main”中的异常 java.util.NoSuchElementException: Hashtable Enumerator 在 java.util.Hashtable$Enumerator.nextElement(未知来源) 在 testscripts.webdrivertest.main(webdrivertest.java:47)

【问题讨论】:

【参考方案1】:

您在循环中调用了两次nextElement()。此调用将枚举指针向前移动。 你应该像下面这样修改你的代码:

while (e.hasMoreElements()) 
    String param = e.nextElement();
    System.out.println(param);

【讨论】:

【参考方案2】:
for (String key : Collections.list(e))
    System.out.println(key);

【讨论】:

效率极低! Collections.list 创建一个新的 ArrayList 并将枚举中的每个值复制到新列表中,然后返回列表引用。为可爱的语法付出了很大的代价。 @AndyBrown 如果您的列表很小或不是很大,则不会。而且.. 可爱的语法有助于使代码更清晰。 一个较短的变体是 Collections.list(e).forEach(System.out::println); @AndyBrown 这并不是非常低效。这是 O(2n) 与 O(n),相同的数量级。对于足够大的列表,使用并行流和正确的硬件可能会更快地遍历列表。 @anataliocs with Collections.list(e) 在内部使用初始默认大小为 10 的 ArrayList,我可能会涉及相当多的数组分配和副本。当 ArrayList 超过容量时,它的当前大小会增长一半,具有 1000 个元素的枚举将创建不少于 13 个数组(大小为 10、15、22、33、49、73、109、163、244、366、549、823 , 1234) 并复制其中的 12 个【参考方案3】:

每次调用e.nextElement() 时,都会从迭代器中获取下一个对象。您必须在每次通话之间检查e.hasMoreElement()


例子:

while(e.hasMoreElements())
    String param = e.nextElement();
    System.out.println(param);

【讨论】:

这似乎是第一个回复。这是经过验证的答案还是我遗漏了什么? @PascalGanaye 这个答案错过了问题包含的错误。【参考方案4】:

您正在调用 nextElement 两次。像这样重构:

while(e.hasMoreElements())


String param = (String) e.nextElement();
System.out.println(param);

【讨论】:

【参考方案5】:

您在循环内调用了两次e.nextElement(),而您只能保证可以毫无例外地调用一次。像这样重写循环:

while(e.hasMoreElements())
  String param = e.nextElement();
  System.out.println(param);

【讨论】:

【参考方案6】:

您在循环中调用了 nextElement 两次。你应该只调用一次,否则它会向前移动两次:

while(e.hasMoreElements())
    String s = e.nextElement();
    System.out.println(s);

【讨论】:

【参考方案7】:

每次您执行e.nextElement() 时,您都会跳过一个。因此,您在循环的每次迭代中都跳过了两个元素。

【讨论】:

以上是关于遍历 hastable 键的枚举会引发 NoSuchElementException 错误的主要内容,如果未能解决你的问题,请参考以下文章

《C#零基础入门之百识百例》(八十七)系统类HasTable哈希表解析 -- 几种遍历方式

EnumMap 源码分析

IEnumerable接口引发的思考

遍历 Perl 哈希键的最安全方法是啥?

为啥 HashMap 和 Hastable 的 put 方法有区别?

python 实现一个简单的hastable及其操作。