遍历 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哈希表解析 -- 几种遍历方式