2017-05-05 25 views
2

我想创建一个不可变的番石榴multisets数量(> 2)的总和不可变的看法。多重列表在列表中。我不想将内容复制到新的多重集中。我大概可以使用Multisets.sum(Multiset, Multiset)并减少我的Multisets流,但为每个中间步骤创建一个总和multiset似乎有点浪费。有没有更好的办法?合并几个番石榴multisets到一个

换句话说:我想要一个类似于Multisets.sum(Multiset, Multiset)的方法,但是对于multisets而不是仅仅两个。签名可能是:<T> Multiset<T> sum(List<Multiset<T>>)

+0

你能举个例子吗? – notionquest

+0

@notionquest我有一个'List >'',我想要一个不可变的'Multiset ',这些多重音色组合在一起,就像'Multisets.sum(Multiset,Multiset)'一样。这不是一个真正的例子,希望它能澄清我的问题。 – Rinke

+0

您可以考虑在https://github.com/google/guava/issues上建议添加“Multisets.sum(Multiset ...)”的问题。 – mfulton26

回答

2

其实Multisets.sum(Multiset, Multiset)是以它不复制内容的方式实现的,而是创建一个超过两个多重集的视图,所以在你的情况下循环遍历多重集列表并且只将最终结果复制到一个新的不可变多重集是好的(视图的开销不应该是对于少数多重分配)。使用Java 8可以结合多集的sumStream#reduce

public <T> Multiset<T> sum(final List<Multiset<T>> multisets) 
{ 
    return multisets.stream().reduce(ImmutableMultiset.of(), Multisets::sum); 
} 

编辑

然而虽然,我将不再参与上述方法复制,因为@LouisWasserman指出最优化的解决方案(因人而异)可能是只是积聚在新的多集的结果:

public <T> ImmutableMultiset<T> sum(final List<Multiset<T>> multisets) 
{ 
    final ImmutableMultiset.Builder<T> builder = ImmutableMultiset.builder(); 
    multisets.forEach(builder::addAll); 
    return builder.build(); 
} 

有专门的视图类(见@ OliverGregoire的答案)也是,如果需要的选项。

+0

是的,但是在减少过程中会不会创造出很多中间多集?最终的multiset基本上是所有这些multisets的大树。这看起来很浪费。你怎么看? – Rinke

+0

创建一个视图类是便宜的,对于大小<100的输入列表(我编制了这个数字)它应该没有关系,并且会是一个不成熟的优化IMO。 *如果您想在此优化,请先做基准并分析您的代码。较小的代码库和重新使用库的好东西对于我来说比创建另一个类(你必须维护它)执行非常狭窄的任务更大。 – Xaerxess

+0

谢谢。合理的点。其实我已经按照你的建议以类似的方式实施了它,但是如果有更好的解决方案,我仍然很好奇。 – Rinke

4

有没有方法可以做到这一点。

但是,请记住,番石榴是Apache许可证下的许可证,所以您可以查看并重用代码(只要您遵守许可证要求即可)。

来源可用here

考虑到这一点,你可以创建自己的类,在结构上类似于番石榴的Multisets.sum(Multiset,Multiset)

public class SummedMultiset<T> extends AbstractMultiset<T> { 
    private final ImmutableList<Multiset<T>> multisets; 
    public SummedMultiset(List<Multiset<T>> multisets) { 
    this.multisets = ImmutableList.copyOf(multisets); 
    } 
    @Override public int count(Object element) { 
    return multisets.stream().mapToInt(m -> m.count(element)).sum(); 
    } 
    // Fill all the other methods seen in Guava's source. 
} 

当然,你可以隐藏的方法背后的实现:

public class MoreMultisets { 
    public static Multiset<T> sum(List<Multiset<T>> multisets) { 
    return new SummedMultiset<>(multisets); 
    } 
}