简体   繁体   中英

How to iterate through a HashMap with two iterators?

I want to search a HashMap for duplicates. Currently this is my HashMap:

HashMap<String, HashMap<String, String>>

I was going to create two Iterators, one i and another j , and two loops. The first while loop will have the index of i and then the second loop will have the index of j but j is == to i before the loop begins.

Iterator<Entry<String, HashMap<String, String>>> i = listings.entrySet().iterator();
while(i.hasNext()) {
    HashMap<String, String> entry = i.next().getValue();
    Iterator<Entry<String, HashMap<String, String>>> j = i;

    while(j.hasNext()) {
        j.next();
        // DO STUFF
    }
}

But this doesn't work because when i call j.next() , it also changes the index of i .

It looks to you want one iterator that goes through the whole map, and for each iteration, you want another iterator that goes through PART of the map starting with where the first iterator is currently pointing. Java doesn't have a way to set up an iterator that starts in the middle. Furthermore, I don't think it's guaranteed that the iterator will go through in a particular order; so if you try creating a new iterator and then just skipping over the first N to get to the point you want, I wouldn't count on that to work.

You might want to try converting the set of Map.Entry objects to an array:

Set <Map.Entry<String, HashMap<String, String>>> entrySet =
        listings.entrySet();
Map.Entry<String, HashMap<String, String>>[] entryArr =
    (Map.Entry<String, HashMap<String, String>>[])
        entrySet.toArray ();

for (int i = 0; i < arr.length; i++) {
    for (int j = i; j < arr.length; j++) {
         // something
    }
}

Unfortunately, this will give warnings about unchecked operations when you use toArray(), but I don't know how to get around that.

EDIT: Following Louis Wasserman's suggestion (thanks!):

Set <Map.Entry<String, HashMap<String, String>>> entrySet =
        listings.entrySet();
ArrayList<Map.Entry<String, HashMap<String, String>>> entryArr =
    new ArrayList<Map.Entry<String, HashMap<String, String>>> (entrySet);

for (int i = 0; i < arr.size(); i++) {
    for (int j = i; j < arr.size(); j++) {
         // something; use arr.get(i), arr.get(j) to get at the keys/values
    }
}
j = i

You have two reference to the same iterator.

If you want another iterator, you need to call .iterator() again.

I want to search a HashMap for duplicates

Assuming you mean duplicate values , you can do

public static <K, V> List<V> duplicatedValues(Map<K, ? extends V> map) {
  Collection<? extends V> values = map.values();
  Set<? extends V> valueSet = new HashSet<V>(values);
  List<V> dupes = new ArrayList<V>();
  if (valueSet.size() != map.size()) {
    for (V value : values) {
      if (!valueSet.remove(value)) {
        // Already seen
        dupes.add(value);
      }
    }
  }
  return dupes;
}

您使用两个引用i and j指向相同的迭代器,因此当一个更改对象的状态时,其他引用也将看到更新的状态。

You need an iterator from the hashmap entry in your first hashmap.

Iterator<Entry<String, HashMap<String, String>>> i = listings.entrySet().iterator();
while(i.hasNext()) {
    HashMap<String, String> entry = i.next().getValue();

    Iterator<Entry<String, HashMap<String, String>>> j = entry.iterator();
    while(j.hasNext()) {
        j.next();
         // DO STUFF
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM