简体   繁体   English

如何使用两个迭代器迭代HashMap?

[英]How to iterate through a HashMap with two iterators?

I want to search a HashMap for duplicates. 我想在HashMap中搜索重复项。 Currently this is my HashMap: 目前这是我的HashMap:

HashMap<String, HashMap<String, String>>

I was going to create two Iterators, one i and another j , and two loops. 我打算创建两个迭代器,一个i和另一个j ,以及两个循环。 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. 第一个while循环将具有i的索引,然后第二个循环将具有j的索引但是j在循环开始之前是==i

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 . 但是这不起作用,因为当我调用j.next() ,它也会改变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. 它看起来你想要一个穿过整个映射的迭代器,并且对于每次迭代,你想要另一个迭代器穿过映射的PART,从第一个迭代器当前指向的位置开始。 Java doesn't have a way to set up an iterator that starts in the middle. Java无法设置从中间开始的迭代器。 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. 因此,如果您尝试创建一个新的迭代器,然后只是跳过前N来达到您想要的点,我就不会指望它能够工作。

You might want to try converting the set of Map.Entry objects to an array: 您可能想尝试将Map.Entry对象集转换为数组:

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. 不幸的是,当你使用toArray()时,这会给出关于未经检查的操作的警告,但我不知道如何解决这个问题。

EDIT: Following Louis Wasserman's suggestion (thanks!): 编辑:按照Louis Wasserman的建议(谢谢!):

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. 如果你想要另一个迭代器,你需要再次调用.iterator()

I want to search a HashMap for duplicates 我想在HashMap中搜索重复项

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. 您需要第一个hashmap中的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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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