Reputation: 57
I have the issue that my loop does not break and returns the same value
public Map<String, String> getKeysByValue(Map<String, Map<String, Peple>> map, Collection<Peple> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
while (value.iterator().hasNext()) {
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
String verified = value.iterator().next().gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), value.iterator().next().getName());
}
}
}
The problem here is that the same value kets put in the map for every key (value.iterator().next().getName()) always returns the same string
Upvotes: 1
Views: 978
Reputation: 2021
This code works fine with the below input:
import java.util.*;
public class Test {
public static void main(String[] ar){
Map<String, People> entry1 = new HashMap<String , People>();
People people1 = new People("true","name1");
People people2 = new People("false","name2");
People people3 = new People("true","name3");
entry1.put("user1", people1);
entry1.put("user2", people2);
entry1.put("user3", people3);
Map<String, People> entry2 = new HashMap<String , People>();
People people4 = new People("true","name1");
People people5 = new People("false","name2");
People people6 = new People("true","name3");
entry2.put("user1", people4);
entry2.put("user2", people5);
entry2.put("user3", people6);
Map<String, Map<String, People>> map2 = new HashMap<String, Map<String,
People>>();
map2.put("set1",entry1);
map2.put("set2",entry2);
Collection<People> strings = new ArrayList<>();
strings.add(people1);
strings.add(people6);
strings.add(people5);
strings.add(people3);
strings.add(people2);
getKeysByValue(map2, strings);
}
public static Map<String, String> getKeysByValue(Map<String, Map<String, People>> map, Collection<People> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
Iterator<People> it = value.iterator();
while (it.hasNext()) {
People people = it.next();
for (Map.Entry<String, Map<String, People>> entry : map.entrySet()) {
for (Map.Entry<String, People> entry1 : entry.getValue().entrySet()) {
String verified = people.getVerified();
System.out.println(verified);
System.out.println("Key : "+entry1.getKey() +" Value : "+entry1.getValue().getVerified());
if (verified.equals(entry1.getValue().getVerified())) {
stringStringMap.put(entry1.getKey(), people.getName());
}
}
}
}
System.out.println(stringStringMap);
return stringStringMap;
}
}
People.java
public class People {
String verified;
public People(String verified, String name){
this.verified = verified;
this.name = name;
}
public String getVerified() {
return verified;
}
public String getName() {
return name;
}
String name;
}
Upvotes: 1
Reputation: 1205
I think the below would be a correct approach for your problem:
public Map<String, String> getKeysByValue(Map<String, Map<String, Peple>> map, Collection<Peple> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
Iterator<People> peopleIterator = value.iterator();
while (peopleIterator.hasNext()) {
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
People people = peopleIterator.next();
String verified = people.gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), people.getName());
}
}
}
You need to store the iterator in a variable.
Consider below simple code :
Collection<String> strings = new ArrayList<>();
strings.add("value1");
strings.add("value2");
strings.add("value3");
strings.add("value4");
while (strings.iterator.hasNext())
{
System.out.println(strings.iterator.next());
}
This will run infinitely and will only print value1, but if you modify the code as below :
Collection<String> strings = new ArrayList<>();
strings.add("value1");
strings.add("value2");
strings.add("value3");
strings.add("value4");
Iterator<String> stringIterator = strings.iterator();
while (stringIterator.hasNext())
{
System.out.println(stringIterator.next());
}
It runs smooth.
You can learn more about iterator here : https://www.geeksforgeeks.org/how-to-use-iterator-in-java/
ALso, I think as you are calling iterator twice without checking hasNext() on the second call, it can throw java.util.NoSuchElementException
Upvotes: 1
Reputation: 2528
Every time you call value.iterator()
new Iterator
object is created from scratch, pointing to a first element. To avoid it, store first result of calling it into local variable.
Iterator<Peple> it = value.iterator();
while(it.hasNext()){
// your remaiing code
}
Upvotes: 1
Reputation: 20914
Try this:
public Map<String, String> getKeysByValue(Map<String, Map<String, Peple>> map, Collection<Peple> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
Iterator<Peple> iterator = value.iterator();
while (iterator.hasNext()) {
Peple p = iterator.next();
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
String verified = p.gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), p.getName());
}
}
}
}
}
Upvotes: 0
Reputation: 794
You are calling next() twice on that iterator. That moves it ahead and picks up the name of the next People, which might not be verified.
I believe you just want to get the name if it's a verified Peple?
while (value.iterator().hasNext()) {
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
Peple nextPeple = value.iterator().next();
String verified = nextPeple.gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), nextPeple.getName());
}
}
}
}
Upvotes: 1