2011-05-10 66 views
40

Guava中是否有flatten方法 - 或將Iterable<Iterable<T>>轉換爲Iterable<T>的簡單方法?Flattable a Iterable <Iterable<T>> Guava

我有一個Multimap<K, V> [sourceMultimap],我想返回鍵匹配某些謂詞[keyPredicate]的所有值。所以現在我有:

Iterable<Collection<V>> vals = Maps.filterKeys(sourceMultimap.asMap(), keyPredicate).values(); 

Collection<V> retColl = ...; 
for (Collection<V> vs : vals) retColl.addAll(vs); 
return retColl; 

我看過了番石榴文檔,但沒有跳出來。我只是檢查我沒有錯過任何東西。否則,我會將我的三條線提取到一個簡短的扁平通用方法中,並保持原樣。

回答

72

Iterables.concat method滿足這一要求:

public static <T> Iterable<T> concat(Iterable<? extends Iterable<? extends T>> inputs) 
+0

非常感謝 - 不知道我是怎麼錯過它的! – 2011-05-10 11:35:34

+6

我猜想這是因爲這只是一個級別的連接,而不是真正變平:) – 2011-05-10 17:05:28

+0

另外,如果正在從番石榴轉換中生成一個集合,則可以使用FluentIterable transformAndConcat:http://docs.guava-libraries.googlecode。 com/git/javadoc/com/google/common/collect/FluentIterable.html#transformAndConcat(com.google.common.base.Function) – 2014-12-08 18:51:52

2

從Java 8中,你可以做到這一點沒有番石榴。這有點笨重,因爲Iterable doesn't directly provide streams需要使用StreamSupport,但它不需要像問題中的代碼那樣創建新的集合。

private static <T> Iterable<T> concat(Iterable<? extends Iterable<T>> foo) { 
    return() -> StreamSupport.stream(foo.spliterator(), false) 
     .flatMap(i -> StreamSupport.stream(i.spliterator(), false)) 
     .iterator(); 
} 
+0

不符合我的需要,因爲我的迭代器很懶,但是所有的懶惰都會在轉換時丟失這樣一個迭代器來流。 – odiszapc 2016-02-27 16:40:41

+0

@odiszapc我不確定你的意思。 Iterable.spliterator()只是返回一個包裝Iterable.iterator()的Spliterator;在流的終端操作開始之前不繪製任何元素。同樣,StreamSupport.stream明確記錄,直到終端操作開始時纔開始查詢分割器。所以我認爲你說你的頂級_iterable_是懶惰的,你想延遲調用iterator()?在這種情況下,使用StreamSupport.stream重載獲取供應商('StreamSupport.stream(() - > foo.spliterator(),false)')。 – 2016-02-27 21:54:04

+2

@odiszapc否則,如果您有時間製作一個答案,我會對一個最小范例感興趣,因爲我會從中學到一些東西。 – 2016-02-27 21:54:56

相關問題