【问题标题】:Iterate over nested maps迭代嵌套地图
【发布时间】:2013-03-16 09:06:32
【问题描述】:

我将这些方法放在一起来帮助迭代嵌套地图(用于another SO question)。

你可以清楚地看到,前两个方法实际上几乎完全相同,除了它们的泛型,一个调用iV,另一个调用iiV。有什么办法可以将它们折叠成一种方法,或者至少将机制的清晰重复移到一个地方?

如果做得好,应该可以迭代任何深度的嵌套地图。

// Iterating across Maps of Maps of Maps.
static <K1, K2, K3, V> Iterator<Iterator<Iterator<V>>> iiiV(Map<K1, Map<K2, Map<K3, V>>> mmm) {
  final Iterator<Map<K2, Map<K3, V>>> mmi = iV(mmm);
  return new Iterator<Iterator<Iterator<V>>>() {
    @Override
    public boolean hasNext() {
      return mmi.hasNext();
    }

    @Override
    public Iterator<Iterator<V>> next() {
      return iiV(mmi.next());
    }

    @Override
    public void remove() {
      mmi.remove();
    }
  };
}

// Iterating across Maps of Maps.
static <K1, K2, V> Iterator<Iterator<V>> iiV(Map<K1, Map<K2, V>> mm) {
  final Iterator<Map<K2, V>> mi = iV(mm);
  return new Iterator<Iterator<V>>() {
    @Override
    public boolean hasNext() {
      return mi.hasNext();
    }

    @Override
    public Iterator<V> next() {
      return iV(mi.next());
    }

    @Override
    public void remove() {
      mi.remove();
    }
  };
}

// Iterating across Map values.
static <K, V> Iterator<V> iV(final Map<K, V> map) {
  return iV(map.entrySet().iterator());
}

// Iterating across Map.Entries.
static <K, V> Iterator<V> iV(final Iterator<Map.Entry<K, V>> mei) {
  return new Iterator<V>() {
    @Override
    public boolean hasNext() {
      return mei.hasNext();
    }

    @Override
    public V next() {
      return mei.next().getValue();
    }

    @Override
    public void remove() {
      mei.remove();
    }
  };
}

【问题讨论】:

  • 如果要迭代 n 深度图,方法签名和返回类型是什么?
  • @khachik - 查看链接中的完整答案。您可以使用NestedIterator(NestedIterator(Iterator&lt;Iterator&lt;Iterator&lt;V&gt;&gt;&gt; i)) 返回Iterator&lt;V&gt;。这些方法只是为 NestedIterator 构造函数从嵌套的 Maps 构建嵌套迭代器的助手。

标签: java generics nested-generics


【解决方案1】:

为什么不:

static <K, V> Iterator<V> iV(final Iterator<V> mei) {
   return new Iterator<V>() {
     @Override
     public boolean hasNext() {
       return mei.hasNext();
     }

     @Override
     public V next() {
       if (Iterator.class.isAssignableFrom(V.class)) {
         Iterator it = iV((Iterator)V);
         return it.hasNext() ? it.next() : ((Iterator)mei.next()).next();
       }
       else
         return mei.next().getValue();
     }

     @Override
     public void remove() {
       mei.remove();
    }
  };
}

(未测试)

【讨论】:

  • 由于类型擦除,不确定您是否可以执行V.class,但我喜欢这个想法。也许是mei.getClass()
  • 哦,我认为你是对的。但是mei.getClass() 只会返回Iterator.class。您可能应该使用一个元素并使用element.getClass() 检查这个元素,但要小心考虑空迭代器等。我已经遇到过类似的情况,我认为没有更清洁的解决方案...... :(
猜你喜欢
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多