1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors 3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License. 6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at 7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and 14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License. 15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect; 18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 19090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport static com.google.common.base.Preconditions.checkNotNull; 20090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 220888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.annotations.GwtIncompatible; 230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.Multiset.Entry; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.primitives.Ints; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Arrays; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Iterator; 30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable; 32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/** 34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * An immutable hash-based multiset. Does not permit null elements. 35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>Its iterator orders elements according to the first appearance of the 37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * element among the items passed to the factory method or builder. When the 38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * multiset contains multiple instances of an element, those instances are 39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * consecutive in the iteration order. 40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 417dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>See the Guava User Guide article on <a href= 427dd252788645e940eada959bdde927426e2531c9Paul Duffin * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained"> 437dd252788645e940eada959bdde927426e2531c9Paul Duffin * immutable collections</a>. 447dd252788645e940eada959bdde927426e2531c9Paul Duffin * 45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Jared Levy 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library) 48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 490888a09821a98ac0680fad765217302858e70fa4Paul Duffin@GwtCompatible(serializable = true, emulated = true) 500888a09821a98ac0680fad765217302858e70fa4Paul Duffin@SuppressWarnings("serial") // we're overriding default serialization 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// TODO(user): write an efficient asList() implementation 520888a09821a98ac0680fad765217302858e70fa4Paul Duffinpublic abstract class ImmutableMultiset<E> extends ImmutableCollection<E> 530888a09821a98ac0680fad765217302858e70fa4Paul Duffin implements Multiset<E> { 540888a09821a98ac0680fad765217302858e70fa4Paul Duffin 550888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static final ImmutableMultiset<Object> EMPTY = 560888a09821a98ac0680fad765217302858e70fa4Paul Duffin new RegularImmutableMultiset<Object>(ImmutableMap.<Object, Integer>of(), 0); 57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns the empty immutable multiset. 60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 610888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // all supported methods are covariant 62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public static <E> ImmutableMultiset<E> of() { 630888a09821a98ac0680fad765217302858e70fa4Paul Duffin return (ImmutableMultiset<E>) EMPTY; 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable multiset containing a single element. 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if {@code element} is null 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 6.0 (source-compatible since 2.0) 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 720888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // generic array created but never written 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E> ImmutableMultiset<E> of(E element) { 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyOfInternal(element); 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable multiset containing the given elements, in order. 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any element is null 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 6.0 (source-compatible since 2.0) 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 830888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E> ImmutableMultiset<E> of(E e1, E e2) { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyOfInternal(e1, e2); 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable multiset containing the given elements, in order. 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any element is null 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 6.0 (source-compatible since 2.0) 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 940888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E> ImmutableMultiset<E> of(E e1, E e2, E e3) { 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyOfInternal(e1, e2, e3); 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable multiset containing the given elements, in order. 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any element is null 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 6.0 (source-compatible since 2.0) 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E> ImmutableMultiset<E> of(E e1, E e2, E e3, E e4) { 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyOfInternal(e1, e2, e3, e4); 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable multiset containing the given elements, in order. 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any element is null 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 6.0 (source-compatible since 2.0) 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E> ImmutableMultiset<E> of(E e1, E e2, E e3, E e4, E e5) { 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyOfInternal(e1, e2, e3, e4, e5); 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable multiset containing the given elements, in order. 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any element is null 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 6.0 (source-compatible since 2.0) 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // 1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <E> ImmutableMultiset<E> of( 1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin E e1, E e2, E e3, E e4, E e5, E e6, E... others) { 1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new Builder<E>() 1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin .add(e1) 1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin .add(e2) 1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin .add(e3) 1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin .add(e4) 1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin .add(e5) 1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin .add(e6) 1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin .add(others) 1380888a09821a98ac0680fad765217302858e70fa4Paul Duffin .build(); 139090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns an immutable multiset containing the given elements. 143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>The multiset is ordered by the first occurrence of each element. For 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * example, {@code ImmutableMultiset.copyOf([2, 3, 1, 3])} yields a multiset 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with elements in the order {@code 2, 3, 3, 1}. 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any of {@code elements} is null 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 6.0 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <E> ImmutableMultiset<E> copyOf(E[] elements) { 152090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return copyOf(Arrays.asList(elements)); 153090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 154090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 155090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 156090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns an immutable multiset containing the given elements. 157090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 158090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>The multiset is ordered by the first occurrence of each element. For 159090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * example, {@code ImmutableMultiset.copyOf(Arrays.asList(2, 3, 1, 3))} yields 160090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * a multiset with elements in the order {@code 2, 3, 3, 1}. 161090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Despite the method name, this method attempts to avoid actually copying 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the data when it is safe to do so. The exact circumstances under which a 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * copy will or will not be performed are undocumented and subject to change. 165090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 166090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p><b>Note:</b> Despite what the method name suggests, if {@code elements} 167090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * is an {@code ImmutableMultiset}, no copy will actually be performed, and 168090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * the given multiset itself will be returned. 169090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 170090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if any of {@code elements} is null 171090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <E> ImmutableMultiset<E> copyOf( 1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin Iterable<? extends E> elements) { 174090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (elements instanceof ImmutableMultiset) { 1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin @SuppressWarnings("unchecked") // all supported methods are covariant 176090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ImmutableMultiset<E> result = (ImmutableMultiset<E>) elements; 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!result.isPartialView()) { 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 180090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 181090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multiset<? extends E> multiset = (elements instanceof Multiset) 1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin ? Multisets.cast(elements) 184090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson : LinkedHashMultiset.create(elements); 185090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 186090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return copyOfInternal(multiset); 187090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 188090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <E> ImmutableMultiset<E> copyOfInternal(E... elements) { 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyOf(Arrays.asList(elements)); 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static <E> ImmutableMultiset<E> copyOfInternal( 1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin Multiset<? extends E> multiset) { 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copyFromEntries(multiset.entrySet()); 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin static <E> ImmutableMultiset<E> copyFromEntries( 1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin Collection<? extends Entry<? extends E>> entries) { 200090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson long size = 0; 201090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ImmutableMap.Builder<E, Integer> builder = ImmutableMap.builder(); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<? extends E> entry : entries) { 203090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int count = entry.getCount(); 204090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (count > 0) { 205090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // Since ImmutableMap.Builder throws an NPE if an element is null, no 206090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson // other null checks are needed. 207090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson builder.put(entry.getElement(), count); 208090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson size += count; 209090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 210090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 211090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 212090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (size == 0) { 213090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return of(); 214090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new RegularImmutableMultiset<E>( 2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin builder.build(), Ints.saturatedCast(size)); 217090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 218090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 219090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 220090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns an immutable multiset containing the given elements. 221090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 222090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * <p>The multiset is ordered by the first occurrence of each element. For 223090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * example, 224090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * {@code ImmutableMultiset.copyOf(Arrays.asList(2, 3, 1, 3).iterator())} 225090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * yields a multiset with elements in the order {@code 2, 3, 3, 1}. 226090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 227090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if any of {@code elements} is null 228090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 2290888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static <E> ImmutableMultiset<E> copyOf( 2300888a09821a98ac0680fad765217302858e70fa4Paul Duffin Iterator<? extends E> elements) { 231090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Multiset<E> multiset = LinkedHashMultiset.create(); 232090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Iterators.addAll(multiset, elements); 233090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return copyOfInternal(multiset); 234090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 235090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMultiset() {} 237090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public UnmodifiableIterator<E> iterator() { 2397dd252788645e940eada959bdde927426e2531c9Paul Duffin final Iterator<Entry<E>> entryIterator = entrySet().iterator(); 240090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return new UnmodifiableIterator<E>() { 241090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson int remaining; 242090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson E element; 243090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 245090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public boolean hasNext() { 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (remaining > 0) || entryIterator.hasNext(); 247090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 248090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 250090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public E next() { 251090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (remaining <= 0) { 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Entry<E> entry = entryIterator.next(); 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert element = entry.getElement(); 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert remaining = entry.getCount(); 255090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 256090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson remaining--; 257090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return element; 258090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 259090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson }; 260090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 261090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean contains(@Nullable Object object) { 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return count(object) > 0; 265090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 266090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsAll(Collection<?> targets) { 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return elementSet().containsAll(targets); 270090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 271090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 272090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 273090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 274090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 275090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 2767dd252788645e940eada959bdde927426e2531c9Paul Duffin * @deprecated Unsupported operation. 277090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 2787dd252788645e940eada959bdde927426e2531c9Paul Duffin @Deprecated 2790888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public final int add(E element, int occurrences) { 281090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 282090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 283090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 284090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 285090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 286090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 287090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 2887dd252788645e940eada959bdde927426e2531c9Paul Duffin * @deprecated Unsupported operation. 289090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 2907dd252788645e940eada959bdde927426e2531c9Paul Duffin @Deprecated 2910888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public final int remove(Object element, int occurrences) { 293090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 294090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 295090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 296090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 297090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 298090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 299090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 3007dd252788645e940eada959bdde927426e2531c9Paul Duffin * @deprecated Unsupported operation. 301090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 3027dd252788645e940eada959bdde927426e2531c9Paul Duffin @Deprecated 3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public final int setCount(E element, int count) { 305090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 306090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 307090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 308090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 309090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Guaranteed to throw an exception and leave the collection unmodified. 310090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 311090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws UnsupportedOperationException always 3127dd252788645e940eada959bdde927426e2531c9Paul Duffin * @deprecated Unsupported operation. 313090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 3147dd252788645e940eada959bdde927426e2531c9Paul Duffin @Deprecated 3150888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public final boolean setCount(E element, int oldCount, int newCount) { 317090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson throw new UnsupportedOperationException(); 318090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 319090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 3200888a09821a98ac0680fad765217302858e70fa4Paul Duffin @GwtIncompatible("not present in emulated superclass") 3217dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 3220888a09821a98ac0680fad765217302858e70fa4Paul Duffin int copyIntoArray(Object[] dst, int offset) { 3230888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Multiset.Entry<E> entry : entrySet()) { 3240888a09821a98ac0680fad765217302858e70fa4Paul Duffin Arrays.fill(dst, offset, offset + entry.getCount(), entry.getElement()); 3250888a09821a98ac0680fad765217302858e70fa4Paul Duffin offset += entry.getCount(); 326090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 3270888a09821a98ac0680fad765217302858e70fa4Paul Duffin return offset; 328090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 329090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 3300888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public boolean equals(@Nullable Object object) { 3310888a09821a98ac0680fad765217302858e70fa4Paul Duffin return Multisets.equalsImpl(this, object); 3320888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3330888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3340888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public int hashCode() { 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Sets.hashCodeImpl(entrySet()); 336090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 337090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 3380888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public String toString() { 339090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return entrySet().toString(); 340090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 341090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 342090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson private transient ImmutableSet<Entry<E>> entrySet; 343090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 3440888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3457dd252788645e940eada959bdde927426e2531c9Paul Duffin public ImmutableSet<Entry<E>> entrySet() { 346090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson ImmutableSet<Entry<E>> es = entrySet; 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (es == null) ? (entrySet = createEntrySet()) : es; 348090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 349090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 3500888a09821a98ac0680fad765217302858e70fa4Paul Duffin private final ImmutableSet<Entry<E>> createEntrySet() { 3510888a09821a98ac0680fad765217302858e70fa4Paul Duffin return isEmpty() ? ImmutableSet.<Entry<E>>of() : new EntrySet(); 3520888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 353dbd967a6e5c96cc1a97c5521f88dc1564ba2f81bPaul Duffin 3540888a09821a98ac0680fad765217302858e70fa4Paul Duffin abstract Entry<E> getEntry(int index); 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3560888a09821a98ac0680fad765217302858e70fa4Paul Duffin private final class EntrySet extends ImmutableSet<Entry<E>> { 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean isPartialView() { 3597dd252788645e940eada959bdde927426e2531c9Paul Duffin return ImmutableMultiset.this.isPartialView(); 360090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 361090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3630888a09821a98ac0680fad765217302858e70fa4Paul Duffin public UnmodifiableIterator<Entry<E>> iterator() { 3640888a09821a98ac0680fad765217302858e70fa4Paul Duffin return asList().iterator(); 3650888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3660888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3670888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3680888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableList<Entry<E>> createAsList() { 3690888a09821a98ac0680fad765217302858e70fa4Paul Duffin return new ImmutableAsList<Entry<E>>() { 3700888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3710888a09821a98ac0680fad765217302858e70fa4Paul Duffin public Entry<E> get(int index) { 3720888a09821a98ac0680fad765217302858e70fa4Paul Duffin return getEntry(index); 3730888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3740888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3750888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3760888a09821a98ac0680fad765217302858e70fa4Paul Duffin ImmutableCollection<Entry<E>> delegateCollection() { 3770888a09821a98ac0680fad765217302858e70fa4Paul Duffin return EntrySet.this; 3780888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3790888a09821a98ac0680fad765217302858e70fa4Paul Duffin }; 3800888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3810888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3820888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3830888a09821a98ac0680fad765217302858e70fa4Paul Duffin public int size() { 3840888a09821a98ac0680fad765217302858e70fa4Paul Duffin return elementSet().size(); 3850888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 3860888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3870888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean contains(Object o) { 389090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (o instanceof Entry) { 390090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson Entry<?> entry = (Entry<?>) o; 391090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (entry.getCount() <= 0) { 392090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 393090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 3947dd252788645e940eada959bdde927426e2531c9Paul Duffin int count = count(entry.getElement()); 395090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return count == entry.getCount(); 396090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 397090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return false; 398090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 399090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int hashCode() { 4027dd252788645e940eada959bdde927426e2531c9Paul Duffin return ImmutableMultiset.this.hashCode(); 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4050888a09821a98ac0680fad765217302858e70fa4Paul Duffin // We can't label this with @Override, because it doesn't override anything 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // in the GWT emulated version. 4077dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO(cpovirk): try making all copies of this method @GwtIncompatible instead 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object writeReplace() { 4097dd252788645e940eada959bdde927426e2531c9Paul Duffin return new EntrySetSerializedForm<E>(ImmutableMultiset.this); 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4127dd252788645e940eada959bdde927426e2531c9Paul Duffin private static final long serialVersionUID = 0; 4137dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4157dd252788645e940eada959bdde927426e2531c9Paul Duffin static class EntrySetSerializedForm<E> implements Serializable { 4167dd252788645e940eada959bdde927426e2531c9Paul Duffin final ImmutableMultiset<E> multiset; 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4187dd252788645e940eada959bdde927426e2531c9Paul Duffin EntrySetSerializedForm(ImmutableMultiset<E> multiset) { 4197dd252788645e940eada959bdde927426e2531c9Paul Duffin this.multiset = multiset; 420090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 421090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 4227dd252788645e940eada959bdde927426e2531c9Paul Duffin Object readResolve() { 4237dd252788645e940eada959bdde927426e2531c9Paul Duffin return multiset.entrySet(); 4247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 425090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 426090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class SerializedForm implements Serializable { 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Object[] elements; 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int[] counts; 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SerializedForm(Multiset<?> multiset) { 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int distinct = multiset.entrySet().size(); 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert elements = new Object[distinct]; 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert counts = new int[distinct]; 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int i = 0; 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Entry<?> entry : multiset.entrySet()) { 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert elements[i] = entry.getElement(); 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert counts[i] = entry.getCount(); 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i++; 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 442090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object readResolve() { 4440888a09821a98ac0680fad765217302858e70fa4Paul Duffin LinkedHashMultiset<Object> multiset = 4450888a09821a98ac0680fad765217302858e70fa4Paul Duffin LinkedHashMultiset.create(elements.length); 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < elements.length; i++) { 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert multiset.add(elements[i], counts[i]); 448090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImmutableMultiset.copyOf(multiset); 450090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 451090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 453090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 454090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 4550888a09821a98ac0680fad765217302858e70fa4Paul Duffin // We can't label this with @Override, because it doesn't override anything 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // in the GWT emulated version. 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object writeReplace() { 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new SerializedForm(this); 459090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 460090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 461090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 462090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns a new builder. The generated builder is equivalent to the builder 463090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * created by the {@link Builder} constructor. 464090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 465090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public static <E> Builder<E> builder() { 466090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return new Builder<E>(); 467090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 468090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 469090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A builder for creating immutable multiset instances, especially {@code 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public static final} multisets ("constant multisets"). Example: 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <pre> {@code 473090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public static final ImmutableMultiset<Bean> BEANS = 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new ImmutableMultiset.Builder<Bean>() 476090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * .addCopies(Bean.COCOA, 4) 477090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * .addCopies(Bean.GARDEN, 6) 478090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * .addCopies(Bean.RED, 8) 479090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * .addCopies(Bean.BLACK_EYED, 10) 480090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * .build();}</pre> 481090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 4820888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Builder instances can be reused; it is safe to call {@link #build} multiple 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * times to build multiple multisets in series. 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library) 486090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static class Builder<E> extends ImmutableCollection.Builder<E> { 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Multiset<E> contents; 489090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 490090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 491090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Creates a new builder. The returned builder is equivalent to the builder 492090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * generated by {@link ImmutableMultiset#builder}. 493090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Builder() { 4950888a09821a98ac0680fad765217302858e70fa4Paul Duffin this(LinkedHashMultiset.<E>create()); 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Builder(Multiset<E> contents) { 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.contents = contents; 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 501090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 502090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 503090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds {@code element} to the {@code ImmutableMultiset}. 504090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 505090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param element the element to add 506090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} object 507090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code element} is null 508090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 5090888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Builder<E> add(E element) { 510090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson contents.add(checkNotNull(element)); 511090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 512090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 513090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 514090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 515090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds a number of occurrences of an element to this {@code 516090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * ImmutableMultiset}. 517090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 518090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param element the element to add 519090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param occurrences the number of occurrences of the element to add. May 520090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * be zero, in which case no change will be made. 521090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} object 522090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code element} is null 523090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws IllegalArgumentException if {@code occurrences} is negative, or 524090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * if this operation would result in more than {@link Integer#MAX_VALUE} 525090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * occurrences of the element 526090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 527090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public Builder<E> addCopies(E element, int occurrences) { 528090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson contents.add(checkNotNull(element), occurrences); 529090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 530090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 531090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 532090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 533090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds or removes the necessary occurrences of an element such that the 534090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * element attains the desired count. 535090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 536090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param element the element to add or remove occurrences of 537090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param count the desired count of the element in this multiset 538090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} object 539090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code element} is null 540090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws IllegalArgumentException if {@code count} is negative 541090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 542090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson public Builder<E> setCount(E element, int count) { 543090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson contents.setCount(checkNotNull(element), count); 544090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 545090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 546090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 547090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 548090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds each element of {@code elements} to the {@code ImmutableMultiset}. 549090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 550090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param elements the elements to add 551090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} object 552090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code elements} is null or contains a 553090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * null element 554090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 5550888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Builder<E> add(E... elements) { 556090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson super.add(elements); 557090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 558090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 559090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 560090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 561090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds each element of {@code elements} to the {@code ImmutableMultiset}. 562090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 563090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param elements the {@code Iterable} to add to the {@code 564090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * ImmutableMultiset} 565090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} object 566090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code elements} is null or contains a 567090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * null element 568090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 5690888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Builder<E> addAll(Iterable<? extends E> elements) { 570090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson if (elements instanceof Multiset) { 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Multiset<? extends E> multiset = Multisets.cast(elements); 572090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson for (Entry<? extends E> entry : multiset.entrySet()) { 573090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson addCopies(entry.getElement(), entry.getCount()); 574090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 575090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } else { 576090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson super.addAll(elements); 577090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 578090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 579090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 580090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 581090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 582090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Adds each element of {@code elements} to the {@code ImmutableMultiset}. 583090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * 584090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @param elements the elements to add to the {@code ImmutableMultiset} 585090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @return this {@code Builder} object 586090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @throws NullPointerException if {@code elements} is null or contains a 587090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * null element 588090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 5890888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Builder<E> addAll(Iterator<? extends E> elements) { 590090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson super.addAll(elements); 591090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return this; 592090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 593090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson 594090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson /** 595090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Returns a newly-created {@code ImmutableMultiset} based on the contents 596090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * of the {@code Builder}. 597090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */ 5980888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public ImmutableMultiset<E> build() { 599090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson return copyOf(contents); 600090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 601090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson } 602090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson} 603