【问题标题】:How do I iterate through a Java Linked Hash map?如何遍历 Java Linked Hash map?
【发布时间】:2012-12-06 01:33:12
【问题描述】:

我搜索了这个问题并找到了使用 Map.Entry 的答案,例如 here,但是 getValue() 方法返回了一个 Object 对象,而不是地图中的对象类型。就像下面的示例一样,我需要它返回一个 User 对象,以便我可以使用该类中的方法。但是,当我尝试使用下面的 while 循环时,它永远不会离开循环。我想知道这样做的正确方法。

Map<String, User> users = new LinkedHashMap<String, User>();
users.put(name, user);

while(users.values().iterator().hasNext()){

   currentUser = users.values().iterator().next();
   currentUser.someMethod();
}

【问题讨论】:

  • Map.Entry 方式是您需要键和值时的正确方式。如果getValue() 的编译时返回类型是Object,那么您很可能在Map.Entry 声明中缺少类型参数。
  • 你有没有尝试调试它,看看它卡在哪里?
  • @MattBall 好的,我会再试一次。
  • @loveToCode 是的,它只是通过 while 循环继续运行,并且 .next() 方法每次都返回相同的对象

标签: java hashmap loops


【解决方案1】:

我想知道这样做的正确方法。

您应该使用Map.Entry 类型;您只需要提供类型参数即可与泛型一起使用:

for (Map.Entry<String,User> entry : users.entrySet()) {
    // entry.getValue() is of type User now
}

【讨论】:

  • 那我能做到entry.getValue().someUserMethod();
  • @user1875021 他已经告诉过你entry.getValue() 的类型是User,答案应该很明显。您可以随时尝试。
  • @user1875021 绝对! entry.getValue()User 类型,你可以用它做任何你想做的事情。
  • 使用entrySet()应该有什么好处?他不使用密钥,所以遍历values() 完全可以完成工作还是?
  • @findusl 如果 OP 不打算使用密钥,他当然应该使用 values();就 CPU 周期而言,也许它会更经济一些。我的印象是循环内的代码不是一个完整的片段,并希望给 OP 一些灵活性来访问键和值。
【解决方案2】:

您误用了迭代器,并且忽略了泛型规范。

Iterator<User> it = users.values().iterator();
while (it.hasNext())
{
  User currentUser = it.next();
  currentUser.someMethod();
}

【讨论】:

  • 啊,我明白了。我试过了,但对泛型并不熟悉,所以我一直得到一个对象。谢谢
【解决方案3】:

最简单的迭代方法是使用 for。在 LinkedHashMap 中是这样的:

   private static LinkedHashMap<Integer, String> dataBase = new LinkedHashMap<Integer, String>();

   for(Integer key : dataBase.keySet()) {
         String ret = dataBase.get(key);
    }

Source

【讨论】:

    【解决方案4】:

    每次调用.iterator(),它都会在第一个元素处为您提供一个全新的迭代器。

    您需要调用一次.iterator() 并将其存储在局部变量中。

    【讨论】:

    • 那么喜欢Iterator temp = users.values.iterator();?
    【解决方案5】:

    为此更改您的代码:

    Iterator<User> it = users.values().iterator();
    
        while (it.hasNext())
        {
    
            currentUser = it.next();
            currentUser.someMethod();  
        }
    

    【讨论】:

      【解决方案6】:

      您必须在处理完成后从集合中删除“下一个”。 使用您的代码,它是“下一个”的库存; 例如:如果您的“users.values()”返回一个集合,即

      {{john, 1}, {jen, 2}, {peter, 3}}

      您的 while 循环一直返回 true,因为它一直返回位于第一个索引处的“{john,1}”。 所以这是一个无限的“循环”。这就是迭代器的工作方式。如果 hasNext() 在第一个索引处有一个元素,则 hasNext() 将返回 true,并且 next() 将返回 hasNext() 确认它具有的元素。

      为了让您的循环继续进行,我认为您必须添加一行代码或 2 行代码。见下文:

           Map<String, String> users = new HashMap<String, String>();
          users.put("1", "John");
          users.put("2", "peter");
          users.put("3", "uche");
           Iterator<String> coll = users.values().iterator();
              while(coll.hasNext()){
      
      
             String currentUser = coll.next();
             System.out.print(currentUser);
      
            //coll.remove(currentUser);
          }
      

      希望这会有所帮助..

      我以前的代码可能不是“正确”的方法,但完成了工作并且没有跳过任何第二个元素@EJP。感谢任何方式让我直截了当.. :)

      【讨论】:

      • 您不必删除任何内容。你只需要正确地迭代。此代码将删除并跳过每隔一个元素。 -1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-01
      • 2017-08-18
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多