2013-03-26 153 views
3

我把这些方法放在一起来帮助迭代嵌套地图(对于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(); 
    } 
    }; 
} 
+0

如果要重复上正深度贴图,这将是该方法的签名和返回类型? – khachik 2013-03-26 14:31:55

+0

@khachik - 查看链接中的完整答案。你可以使用'NestedIterator(NestedIterator(Iterator >> i))'''返回'Iterator '。这些方法只是帮助构建嵌套的''NestedIterator'构造函数'Map'的迭代器。 – OldCurmudgeon 2013-03-26 14:45:16

回答

0

为什么不:

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

(未测试)

+0

不知道是否可以通过类型擦除来执行'V.class',但我喜欢这个想法。也许'mei.getClass()'代替。 – OldCurmudgeon 2013-03-26 14:46:48

+0

哦,我认为你是对的。但'mei.getClass()'只会返回'Iterator.class'。你可能需要一个元素,并用'element.getClass()'检查这个元素,但要小心考虑空的迭代器等。我已经有类似的情况,我认为没有更干净的解决方案...... :( – 2013-03-26 15:09:36