SEED
SEED

Reputation: 57

looping through iterator returns the same value

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

Answers (5)

Pakira
Pakira

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

Lazycoder-007
Lazycoder-007

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

Vasily Liaskovsky
Vasily Liaskovsky

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

Abra
Abra

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

fpezzini
fpezzini

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

Related Questions