16

I searched this question and found answers that used the Map.Entry like here, however the getValue() method returned an Object object instead of the type of object in the map. Like in the example below, I need it to return a User object so I can use a method from that class. When I tried using the while loop below however, it never leaves the loop. I was wondering the correct way to do this.

Map<String, User> users = new LinkedHashMap<String, User>();
users.put(name, user);
while(users.values().iterator().hasNext()){
 currentUser = users.values().iterator().next();
 currentUser.someMethod();
}
asked Dec 6, 2012 at 1:33
4
  • The Map.Entry way is the correct way when you need both keys and values. If getValue()'s compile-time return type is an Object then you are likely missing type parameters on the Map.Entry declaration. Commented Dec 6, 2012 at 1:34
  • did you try to debug it and see where it gets stuck? Commented Dec 6, 2012 at 1:35
  • @MattBall Alright I'll try again. Commented Dec 6, 2012 at 1:40
  • @loveToCode Yeah it just keeps going though the while loop and the .next() method returns the same object everytime Commented Dec 6, 2012 at 1:41

6 Answers 6

23

I was wondering the correct way to do this.

You should use the Map.Entry type; you just need to provide type parameters to use with generics:

for (Map.Entry<String,User> entry : users.entrySet()) {
 // entry.getValue() is of type User now
}
user207421
312k44 gold badges321 silver badges493 bronze badges
answered Dec 6, 2012 at 1:41
5
  • Then would I be able to do entry.getValue().someUserMethod(); Commented Dec 6, 2012 at 1:43
  • 1
    @user1875021 As he's already told you that entry.getValue() is of type User, the answer to that should be obvious. You could always try it. Commented Dec 6, 2012 at 1:45
  • @user1875021 Absolutely! entry.getValue() is of type User, you can do anything you would like with it. Commented Dec 6, 2012 at 1:56
  • What is supposed to be the advantage of using entrySet()? He doesn't use the key, so iterating over values() totally get's the job done or? Commented Nov 19, 2019 at 12:33
  • @findusl If OP isn't planning on using the key, of course he should use values(); perhaps it would be slightly more economical in terms of CPU cycles. I was under impression that the code inside the loop wasn't a complete fragment, and wanted to leave OP some flexibility to access the key along with the value. Commented Nov 19, 2019 at 12:49
19

You're misusing the Iterator, and you're omitting the Generics specifications.

Iterator<User> it = users.values().iterator();
while (it.hasNext())
{
 User currentUser = it.next();
 currentUser.someMethod();
}
answered Dec 6, 2012 at 1:42
1
  • Ah I see. I tried that, but wasn't familiar about Generics so I kept getting an Object. Thanks Commented Dec 6, 2012 at 1:45
4

The easiest way to iterare is using for. In a LinkedHashMap it would be like this:

 private static LinkedHashMap<Integer, String> dataBase = new LinkedHashMap<Integer, String>();
 for(Integer key : dataBase.keySet()) {
 String ret = dataBase.get(key);
 }

Source

answered Jun 26, 2014 at 1:08
3

Each time you call .iterator(), it gives you a brand new iterator at the first element.

You need to call .iterator() once and store it in a local variable.

answered Dec 6, 2012 at 1:34
1
  • So like Iterator temp = users.values.iterator();? Commented Dec 6, 2012 at 1:38
0

change your code for this:

Iterator<User> it = users.values().iterator();
 while (it.hasNext())
 {
 currentUser = it.next();
 currentUser.someMethod(); 
 }
answered Dec 6, 2012 at 1:46
-2

You have to remove "next" from the collection after it has been process. with your code, it is stock at "next"; For example: if your "users.values()" returns a collection i.e

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

Your while loops keeps return true and because it keeps returning "{john,1}" which is at the fist index. and so it is an infinite "loop". This is how Iterator works. hasNext() will return true if it has an element at the first index and next() will return that element that hasNext() confirmed it has.

For your loop to progress i think you have to add a line of code or 2. see below:

 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);
 }

hope this helps..

My former code might not be the "right" way to do it but did the job and did not SKIP any second element @ EJP. thanks any way for putting me straight.. :)

answered Dec 6, 2012 at 2:46
1
  • You don't have to remove anything. You just have to iterate correctly. This code will remove and skip every second element. -1 Commented Apr 12, 2014 at 11:00

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.