如何迭代遍历 Java Linked Hash Map?

16

我搜索了这个问题并找到了使用Map.Entry的答案,例如这里,但是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声明中缺少类型参数。 - Matt Ball
你尝试过调试它并查看它在哪里卡住了吗? - loveToCode
@MattBall 好的,我再试一次。 - user1875021
@loveToCode 是的,它只是不断地通过 while 循环,并且 .next() 方法每次都返回相同的对象。 - user1875021
6个回答

23
我在想如何正确地做这件事情。您应该使用Map.Entry类型;只需提供与泛型一起使用的类型参数即可:
for (Map.Entry<String,User> entry : users.entrySet()) {
    // entry.getValue() is of type User now
}

然后我就可以执行 entry.getValue().someUserMethod(); - user1875021
1
@user1875021已经告诉你entry.getValue()的类型是User,所以答案显而易见。你可以尝试一下。 - user207421
@user1875021 当然可以!entry.getValue()User 类型,你可以对它进行任何想做的操作。 - Sergey Kalinichenko
使用 entrySet() 的优势是什么?他不使用键,所以完全可以通过迭代 values() 来完成工作,对吗? - findusl
如果 OP 不打算使用键,那么他应该使用 values();也许这在 CPU 周期方面稍微更经济一些。我认为循环内部的代码不是一个完整的片段,并且希望留给 OP 一些灵活性来访问键以及值。 - Sergey Kalinichenko

19

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

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

啊,我明白了。我尝试过那个,但是我不熟悉泛型,所以一直得到一个对象。谢谢。 - user1875021

4

最简单的迭代方式是使用for循环。在LinkedHashMap中,它的写法如下:

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

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

Source


3
每次调用.iterator()时,它会给你一个全新的迭代器来遍历第一个元素。
你需要调用.iterator()一次并将其存储在本地变量中。

那就像这样 Iterator temp = users.values.iterator(); - user1875021

0

将您的代码改为以下内容:

Iterator<User> it = users.values().iterator();

    while (it.hasNext())
    {

        currentUser = it.next();
        currentUser.someMethod();  
    }

-2

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

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

您的while循环保持返回true,因为它一直返回位于第一个索引处的“{john,1}”,因此它是一个无限“循环”。这就是迭代器的工作原理。hasNext()将在第一个索引处有元素时返回true,并且next()将返回hasNext()确认的该元素。

为了使您的循环进展,我认为您需要添加一行或两行代码。请参见下面:

     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 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接