2011-12-08 22 views
4

我有一種情況,我想從多個源對象中提取多個值到一個集合中。我試圖通過番石榴的轉變來實現這一目標,但遇到了問題,我收回了一些我必須手動「變平」的集合。是否有一種很好的方式直接在平面集合中獲得結果?用番石榴從一個變爲多個

private static final Function<Target, Collection<Integer>> EXTRACT_FUNCTION = new Function<SourceObject, Collection<Integer>>() { 
    @Override 
    public Collection<Integer> apply(SourceObject o) { 
     // extract and return a collection of integers from o 
     return Lists.newArrayList(..); 
    } 
}; 

Collection<SourceObject> sourceObjects = ... 
Collection<Collection<Integer>>> nestedResults = transform(sourceObjects, EXTRACT_FUNCTION); 

// Now I have to manually flatten the results by looping and doing addAll over the nestedResults.. 
// Can this be avoided? 
Collection<Integer> results = flattenNestedResults(nestedResults); 

回答

8

您可以使用番石榴的Iterables.concat(Iterable<E>... coll)到組幾個迭代結果

+0

這是正確的。 Iterables.concat將替代您的flattenNestedResults功能。 –

1

你所問的是一個reduce/fold方法。 http://code.google.com/p/guava-libraries/issues/detail?id=218

也許這是一個更好的主意,你不使用Function,但迭代,並添加到一個集合:目前雖然有一個開放的問題Guava不支持它。番石榴是一個偉大的框架,但它不能做任何事情。

+0

我不知道'Iterables.concat(Iterable ... coll)',你可以使用它,如果你不介意結果是'Iterable'而不是'Collection' – wyz

+0

還有另一個類似的問題:http:///code.google.com/p/guava-libraries/issues/detail?id=546 –

+2

如果你確實需要一個集合,你通常可以將'Iterables.concat()'與一個複製方法(比如'Lists.newArrayList( )','ImmutableList.copyOf()','Sets.newHashSet()'或ImmutableSet.copyOf()'。返回一個Iterable視圖非常聰明,因爲它可以讓你選擇最終的集合類型,而不是爲你任意選擇一個。它也避免了複製元素,如果你不需要一個真正的集合。 –