自动将多个集合合并为一个集合

时间:2013-04-05 20:34:43

标签: java generics collections subclass guava

我有一些像Functions这样的番石榴Function<String,Set<String>>。使用FluentIterable.transform()的{​​{1}}会产生FluentIterable<Set<String>>,但我需要FluentIterable<String>。所以我现在的想法是继承FluentIterable<E>并添加一个新方法transform2(),它只是在返回之前将所有内容合并到一个集合中。

原始转换方法如下所示:

public final <T> FluentIterable<T> transform(Function<? super E, T> function) {
  return from(Iterables.transform(iterable, function));
}

我为我的子类和transform2()方法想到了类似的东西:

public abstract class FluentIterable2<E> extends FluentIterable<E> 
{       
    public final <T> FluentIterable<T> transform2(Function<? super E, Collection<T>> function) {
        // (PROBLEM 1) Eclipse complains: The field FluentIterable<E>.iterable is not visible  
        Iterable<Collection<T>> iterables = Iterables.transform(iterable, function);

        // (PROBLEM 2) Collection<T> merged = new Collection<T>(); // I need a container / collection - which one?
        for(Collection<T> iterable : iterables)
        {
            // merged.addAll(iterable);
        }

        // return from(merged);
    }
}

目前我的新子类存在两个问题,上面标有PROBLEM 1PROBLEM 2

  • 问题1:原始FluentIterable类中的可迭代字段是私有的 - 我该怎么办?我可以在子类中创建一个具有相同名称的新私有字段,那么这样可以吗?我的子类中调用使用该字段的super.someMethod()的方法怎么样?那么他们会使用超类的字段,它可能有不同的值吗?

  • 问题2:我需要一些泛型集合,我可以在其中组合多个集合的内容,但集合是一个接口,所以我无法实例化它。那么,我可以在那里上课?

如果解决方案仅适用于集合,那将是可以接受的,尽管我更喜欢使用集合和列表的解决方案。

感谢您提供任何暗示!

3 个答案:

答案 0 :(得分:6)

FluentIterable.transformAndConcat(stringToSetFunction)不能用于您的用例吗?

答案 1 :(得分:3)

为什么要将FluentIterable作为子类来执行此操作?你只需要一个简单的循环:

Set<String> union = Sets.newHashSet();
for (Set<String> set : fluentIterableOfSets) {
    union.addAll(set);
}

答案 2 :(得分:3)

使用FluentIterable.transformAndConcat(f),其中f是一个函数,将元素映射到元素类型上的某种迭代。

在您的情况下,假设您的Function<String, Set<String>>被称为TOKENIZE,而您的初始Iterable<String>被称为LINES。

然后要获得Set<String>在LINES中保存所有不同的标记,请执行以下操作:

Iterable<String> LINES = ...;
Function<String, Set<String>> TOKENIZE = ...;
Set<String> TOKENS = FluentIterable.from(LINES)
    .transformAndConcat(TOKENIZE)
    .toSet();

但请仔细考虑JB Nizet的回答。尝试两种方式,看看哪种方式更好。