2017-05-05 23 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); 
    } 
}