【问题标题】:How to iterate through a HashMap with two iterators?如何使用两个迭代器迭代 HashMap?
【发布时间】:2013-08-08 20:49:10
【问题描述】:

我想在 HashMap 中搜索重复项。目前这是我的 HashMap:

HashMap<String, HashMap<String, String>>

我将创建两个迭代器,一个 i 和另一个 j,以及两个循环。第一个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
    }
}

但这不起作用,因为当我调用j.next() 时,它也会更改i 的索引。

【问题讨论】:

  • 看起来您需要一个遍历整个地图的迭代器,并且对于每次迭代,您都需要另一个迭代器从第一个迭代器当前指向的位置开始遍历地图的一部分。我不认为 Java 可以让您轻松做到这一点。
  • @ajb 这正是我要找的!

标签: java map hashmap


【解决方案1】:

看起来您需要一个遍历整个映射的迭代器,并且对于每次迭代,您都需要另一个遍历映射的一部分的迭代器,从第一个迭代器当前指向的位置开始。 Java 没有办法设置从中间开始的迭代器。此外,我不认为迭代器会以特定顺序通过。所以如果你尝试创建一个新的迭代器,然后跳过第一个 N 到达你想要的点,我不会指望它工作。

您可能想尝试将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
    }
}

不幸的是,当您使用 toArray() 时,这会发出有关未经检查的操作的警告,但我不知道如何解决这个问题。

编辑:遵循 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
    }
}

【讨论】:

  • 这可能是最好的方法,但我不会使用toArray,而是使用new ArrayList&lt;Map.Entry&lt;String, HashMap&lt;String, String&gt;&gt;&gt;(listings.entrySet()) 并使用ArrayList 而不是数组。
【解决方案2】:
j = i

您有两个对相同迭代器的引用。

如果你想要另一个迭代器,你需要再次调用.iterator()

【讨论】:

  • 那么如何将i的索引复制到j呢?
  • @samwell:多次致电next()
【解决方案3】:

我想在 HashMap 中搜索重复项

假设你的意思是重复的,你可以这样做

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;
}

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      您需要一个来自第一个哈希映射中哈希映射条目的迭代器。

      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
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-19
        • 1970-01-01
        • 1970-01-01
        • 2021-10-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多