【问题标题】:iterating through Enumeration of hastable keys throws NoSuchElementException error遍历 hastable 键的枚举会引发 NoSuchElementException 错误
【发布时间】: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)

【问题讨论】:

    标签: java hashtable enumeration key


    【解决方案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() 时,您都会跳过一个。因此,您在循环的每次迭代中都跳过了两个元素。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-10-03
              • 2011-03-24
              • 2010-12-12
              • 2011-09-01
              • 1970-01-01
              • 2015-01-23
              • 2015-08-13
              相关资源
              最近更新 更多