2013-03-26 195 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