2017-05-05 3 views
2

불변의 뷰를 불변의 구아바 멀티 세트 (> 2)의 합계로 작성하고 싶습니다. 멀티 세트가 목록에 있습니다. 나는 새로운 multiset으로 내용을 복사하고 싶지 않다. 아마도 Multisets.sum(Multiset, Multiset)을 사용하고 Multisets의 스트림을 줄이거 나, 모든 중간 단계에 대해 합계 멀티 세트를 만드는 것은 약간의 낭비입니다. 더 좋은 방법이 있습니까?하나의 Guava 멀티 세트를 하나로 합치십시오.

다른 말로하면 : Multisets.sum(Multiset, Multiset)과 비슷한 방법을 원하지만 두 개가 아닌 멀티 세트 목록을 원합니다. 서명은 <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 사용 MULTISET의 sumStream#reduce로 : @LouisWasserman 가장 최적의 솔루션 (YMMV를) 언급 한 바와 같이

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

편집

위의 방법에 관련된 더 복사가 없을 것이다 그러나 있지만, 수 단지 새로운 MULTISET 결과 축적 : 전용 뷰 클래스를 갖는

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

예, 그렇지만 축소하는 동안 중간 다중 세트를 많이 생성하지 않습니까? 최종 멀티 세트는 기본적으로 모든 멀티 세트의 큰 나무가됩니다. 이것은 낭비가 보인다. 어떻게 생각해? – Rinke

+0

뷰 클래스를 만드는 것이 저렴하고 크기가 <100 인 입력 목록 (그 숫자를 구성 함)은 중요하지 않아 조기 최적화 IMO가됩니다. * 여기에서 최적화하려는 경우 먼저 벤치마킹을 수행하고 코드를 프로파일 링하십시오. 더 좁은 코드베이스를 갖고 라이브러리 재사용을 다시 사용하는 것은 매우 좁은 작업을 위해 아직 다른 클래스 (유지해야하는)를 만드는 것보다 더 큰 이득입니다. – Xaerxess

+0

감사합니다. 합리적인 포인트. 실제로 나는 당신이 제안한 것과 비슷한 방식으로 이미 그것을 구현했지만, 더 좋은 해결책이 있다면 여전히 궁금해하고 있습니다. – Rinke

4

즉시 사용할 수있는 방법은 없습니다.

그러나 Guava는 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); 
    } 
} 
관련 문제