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();
}
6 Answers 6
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
}
-
Then would I be able to do
entry.getValue().someUserMethod();
user1875021– user187502112/06/2012 01:43:46Commented Dec 6, 2012 at 1:43 -
1@user1875021 As he's already told you that
entry.getValue()
is of typeUser
, the answer to that should be obvious. You could always try it.user207421– user20742112/06/2012 01:45:43Commented Dec 6, 2012 at 1:45 -
@user1875021 Absolutely!
entry.getValue()
is of typeUser
, you can do anything you would like with it.Sergey Kalinichenko– Sergey Kalinichenko12/06/2012 01:56:56Commented Dec 6, 2012 at 1:56 -
What is supposed to be the advantage of using
entrySet()
? He doesn't use the key, so iterating overvalues()
totally get's the job done or?findusl– findusl11/19/2019 12:33:29Commented 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.Sergey Kalinichenko– Sergey Kalinichenko11/19/2019 12:49:40Commented Nov 19, 2019 at 12:49
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();
}
-
Ah I see. I tried that, but wasn't familiar about Generics so I kept getting an Object. Thanksuser1875021– user187502112/06/2012 01:45:58Commented Dec 6, 2012 at 1:45
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);
}
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.
-
So like
Iterator temp = users.values.iterator();
?user1875021– user187502112/06/2012 01:38:07Commented Dec 6, 2012 at 1:38
change your code for this:
Iterator<User> it = users.values().iterator();
while (it.hasNext())
{
currentUser = it.next();
currentUser.someMethod();
}
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.. :)
-
You don't have to remove anything. You just have to iterate correctly. This code will remove and skip every second element. -1user207421– user20742104/12/2014 11:00:04Commented Apr 12, 2014 at 11:00
Map.Entry
way is the correct way when you need both keys and values. IfgetValue()
's compile-time return type is anObject
then you are likely missing type parameters on theMap.Entry
declaration.