1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 import static com.google.common.collect.CollectPreconditions.checkNonnegative;
22 import static com.google.common.collect.CollectPreconditions.checkRemove;
23
24 import com.google.common.annotations.Beta;
25 import com.google.common.annotations.GwtCompatible;
26 import com.google.common.base.Objects;
27 import com.google.common.base.Predicate;
28 import com.google.common.base.Predicates;
29 import com.google.common.collect.Multiset.Entry;
30 import com.google.common.primitives.Ints;
31
32 import java.io.Serializable;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.NoSuchElementException;
38 import java.util.Set;
39
40 import javax.annotation.Nullable;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 @GwtCompatible
56 public final class Multisets {
57 private Multisets() {}
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public static <E> Multiset<E> unmodifiableMultiset(
73 Multiset<? extends E> multiset) {
74 if (multiset instanceof UnmodifiableMultiset ||
75 multiset instanceof ImmutableMultiset) {
76
77 @SuppressWarnings("unchecked")
78 Multiset<E> result = (Multiset<E>) multiset;
79 return result;
80 }
81 return new UnmodifiableMultiset<E>(checkNotNull(multiset));
82 }
83
84
85
86
87
88
89
90 @Deprecated public static <E> Multiset<E> unmodifiableMultiset(
91 ImmutableMultiset<E> multiset) {
92 return checkNotNull(multiset);
93 }
94
95 static class UnmodifiableMultiset<E>
96 extends ForwardingMultiset<E> implements Serializable {
97 final Multiset<? extends E> delegate;
98
99 UnmodifiableMultiset(Multiset<? extends E> delegate) {
100 this.delegate = delegate;
101 }
102
103 @SuppressWarnings("unchecked")
104 @Override protected Multiset<E> delegate() {
105
106 return (Multiset<E>) delegate;
107 }
108
109 transient Set<E> elementSet;
110
111 Set<E> createElementSet() {
112 return Collections.<E>unmodifiableSet(delegate.elementSet());
113 }
114
115 @Override
116 public Set<E> elementSet() {
117 Set<E> es = elementSet;
118 return (es == null) ? elementSet = createElementSet() : es;
119 }
120
121 transient Set<Multiset.Entry<E>> entrySet;
122
123 @SuppressWarnings("unchecked")
124 @Override public Set<Multiset.Entry<E>> entrySet() {
125 Set<Multiset.Entry<E>> es = entrySet;
126 return (es == null)
127
128
129 ? entrySet = (Set) Collections.unmodifiableSet(delegate.entrySet())
130 : es;
131 }
132
133 @SuppressWarnings("unchecked")
134 @Override public Iterator<E> iterator() {
135
136 return (Iterator<E>) Iterators.unmodifiableIterator(delegate.iterator());
137 }
138
139 @Override public boolean add(E element) {
140 throw new UnsupportedOperationException();
141 }
142
143 @Override public int add(E element, int occurences) {
144 throw new UnsupportedOperationException();
145 }
146
147 @Override public boolean addAll(Collection<? extends E> elementsToAdd) {
148 throw new UnsupportedOperationException();
149 }
150
151 @Override public boolean remove(Object element) {
152 throw new UnsupportedOperationException();
153 }
154
155 @Override public int remove(Object element, int occurrences) {
156 throw new UnsupportedOperationException();
157 }
158
159 @Override public boolean removeAll(Collection<?> elementsToRemove) {
160 throw new UnsupportedOperationException();
161 }
162
163 @Override public boolean retainAll(Collection<?> elementsToRetain) {
164 throw new UnsupportedOperationException();
165 }
166
167 @Override public void clear() {
168 throw new UnsupportedOperationException();
169 }
170
171 @Override public int setCount(E element, int count) {
172 throw new UnsupportedOperationException();
173 }
174
175 @Override public boolean setCount(E element, int oldCount, int newCount) {
176 throw new UnsupportedOperationException();
177 }
178
179 private static final long serialVersionUID = 0;
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 @Beta
197 public static <E> SortedMultiset<E> unmodifiableSortedMultiset(
198 SortedMultiset<E> sortedMultiset) {
199
200 return new UnmodifiableSortedMultiset<E>(checkNotNull(sortedMultiset));
201 }
202
203
204
205
206
207
208
209
210
211 public static <E> Multiset.Entry<E> immutableEntry(@Nullable E e, int n) {
212 return new ImmutableEntry<E>(e, n);
213 }
214
215 static final class ImmutableEntry<E> extends AbstractEntry<E> implements
216 Serializable {
217 @Nullable final E element;
218 final int count;
219
220 ImmutableEntry(@Nullable E element, int count) {
221 this.element = element;
222 this.count = count;
223 checkNonnegative(count, "count");
224 }
225
226 @Override
227 @Nullable public E getElement() {
228 return element;
229 }
230
231 @Override
232 public int getCount() {
233 return count;
234 }
235
236 private static final long serialVersionUID = 0;
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265 @Beta
266 public static <E> Multiset<E> filter(Multiset<E> unfiltered, Predicate<? super E> predicate) {
267 if (unfiltered instanceof FilteredMultiset) {
268
269
270 FilteredMultiset<E> filtered = (FilteredMultiset<E>) unfiltered;
271 Predicate<E> combinedPredicate
272 = Predicates.<E>and(filtered.predicate, predicate);
273 return new FilteredMultiset<E>(filtered.unfiltered, combinedPredicate);
274 }
275 return new FilteredMultiset<E>(unfiltered, predicate);
276 }
277
278 private static final class FilteredMultiset<E> extends AbstractMultiset<E> {
279 final Multiset<E> unfiltered;
280 final Predicate<? super E> predicate;
281
282 FilteredMultiset(Multiset<E> unfiltered, Predicate<? super E> predicate) {
283 this.unfiltered = checkNotNull(unfiltered);
284 this.predicate = checkNotNull(predicate);
285 }
286
287 @Override
288 public UnmodifiableIterator<E> iterator() {
289 return Iterators.filter(unfiltered.iterator(), predicate);
290 }
291
292 @Override
293 Set<E> createElementSet() {
294 return Sets.filter(unfiltered.elementSet(), predicate);
295 }
296
297 @Override
298 Set<Entry<E>> createEntrySet() {
299 return Sets.filter(unfiltered.entrySet(), new Predicate<Entry<E>>() {
300 @Override
301 public boolean apply(Entry<E> entry) {
302 return predicate.apply(entry.getElement());
303 }
304 });
305 }
306
307 @Override
308 Iterator<Entry<E>> entryIterator() {
309 throw new AssertionError("should never be called");
310 }
311
312 @Override
313 int distinctElements() {
314 return elementSet().size();
315 }
316
317 @Override
318 public int count(@Nullable Object element) {
319 int count = unfiltered.count(element);
320 if (count > 0) {
321 @SuppressWarnings("unchecked")
322 E e = (E) element;
323 return predicate.apply(e) ? count : 0;
324 }
325 return 0;
326 }
327
328 @Override
329 public int add(@Nullable E element, int occurrences) {
330 checkArgument(predicate.apply(element),
331 "Element %s does not match predicate %s", element, predicate);
332 return unfiltered.add(element, occurrences);
333 }
334
335 @Override
336 public int remove(@Nullable Object element, int occurrences) {
337 checkNonnegative(occurrences, "occurrences");
338 if (occurrences == 0) {
339 return count(element);
340 } else {
341 return contains(element) ? unfiltered.remove(element, occurrences) : 0;
342 }
343 }
344
345 @Override
346 public void clear() {
347 elementSet().clear();
348 }
349 }
350
351
352
353
354
355
356
357 static int inferDistinctElements(Iterable<?> elements) {
358 if (elements instanceof Multiset) {
359 return ((Multiset<?>) elements).elementSet().size();
360 }
361 return 11;
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379 @Beta
380 public static <E> Multiset<E> union(
381 final Multiset<? extends E> multiset1, final Multiset<? extends E> multiset2) {
382 checkNotNull(multiset1);
383 checkNotNull(multiset2);
384
385 return new AbstractMultiset<E>() {
386 @Override
387 public boolean contains(@Nullable Object element) {
388 return multiset1.contains(element) || multiset2.contains(element);
389 }
390
391 @Override
392 public boolean isEmpty() {
393 return multiset1.isEmpty() && multiset2.isEmpty();
394 }
395
396 @Override
397 public int count(Object element) {
398 return Math.max(multiset1.count(element), multiset2.count(element));
399 }
400
401 @Override
402 Set<E> createElementSet() {
403 return Sets.union(multiset1.elementSet(), multiset2.elementSet());
404 }
405
406 @Override
407 Iterator<Entry<E>> entryIterator() {
408 final Iterator<? extends Entry<? extends E>> iterator1
409 = multiset1.entrySet().iterator();
410 final Iterator<? extends Entry<? extends E>> iterator2
411 = multiset2.entrySet().iterator();
412
413 return new AbstractIterator<Entry<E>>() {
414 @Override
415 protected Entry<E> computeNext() {
416 if (iterator1.hasNext()) {
417 Entry<? extends E> entry1 = iterator1.next();
418 E element = entry1.getElement();
419 int count = Math.max(entry1.getCount(), multiset2.count(element));
420 return immutableEntry(element, count);
421 }
422 while (iterator2.hasNext()) {
423 Entry<? extends E> entry2 = iterator2.next();
424 E element = entry2.getElement();
425 if (!multiset1.contains(element)) {
426 return immutableEntry(element, entry2.getCount());
427 }
428 }
429 return endOfData();
430 }
431 };
432 }
433
434 @Override
435 int distinctElements() {
436 return elementSet().size();
437 }
438 };
439 }
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 public static <E> Multiset<E> intersection(
456 final Multiset<E> multiset1, final Multiset<?> multiset2) {
457 checkNotNull(multiset1);
458 checkNotNull(multiset2);
459
460 return new AbstractMultiset<E>() {
461 @Override
462 public int count(Object element) {
463 int count1 = multiset1.count(element);
464 return (count1 == 0) ? 0 : Math.min(count1, multiset2.count(element));
465 }
466
467 @Override
468 Set<E> createElementSet() {
469 return Sets.intersection(
470 multiset1.elementSet(), multiset2.elementSet());
471 }
472
473 @Override
474 Iterator<Entry<E>> entryIterator() {
475 final Iterator<Entry<E>> iterator1 = multiset1.entrySet().iterator();
476
477 return new AbstractIterator<Entry<E>>() {
478 @Override
479 protected Entry<E> computeNext() {
480 while (iterator1.hasNext()) {
481 Entry<E> entry1 = iterator1.next();
482 E element = entry1.getElement();
483 int count = Math.min(entry1.getCount(), multiset2.count(element));
484 if (count > 0) {
485 return immutableEntry(element, count);
486 }
487 }
488 return endOfData();
489 }
490 };
491 }
492
493 @Override
494 int distinctElements() {
495 return elementSet().size();
496 }
497 };
498 }
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 @Beta
516 public static <E> Multiset<E> sum(
517 final Multiset<? extends E> multiset1, final Multiset<? extends E> multiset2) {
518 checkNotNull(multiset1);
519 checkNotNull(multiset2);
520
521
522 return new AbstractMultiset<E>() {
523 @Override
524 public boolean contains(@Nullable Object element) {
525 return multiset1.contains(element) || multiset2.contains(element);
526 }
527
528 @Override
529 public boolean isEmpty() {
530 return multiset1.isEmpty() && multiset2.isEmpty();
531 }
532
533 @Override
534 public int size() {
535 return multiset1.size() + multiset2.size();
536 }
537
538 @Override
539 public int count(Object element) {
540 return multiset1.count(element) + multiset2.count(element);
541 }
542
543 @Override
544 Set<E> createElementSet() {
545 return Sets.union(multiset1.elementSet(), multiset2.elementSet());
546 }
547
548 @Override
549 Iterator<Entry<E>> entryIterator() {
550 final Iterator<? extends Entry<? extends E>> iterator1
551 = multiset1.entrySet().iterator();
552 final Iterator<? extends Entry<? extends E>> iterator2
553 = multiset2.entrySet().iterator();
554 return new AbstractIterator<Entry<E>>() {
555 @Override
556 protected Entry<E> computeNext() {
557 if (iterator1.hasNext()) {
558 Entry<? extends E> entry1 = iterator1.next();
559 E element = entry1.getElement();
560 int count = entry1.getCount() + multiset2.count(element);
561 return immutableEntry(element, count);
562 }
563 while (iterator2.hasNext()) {
564 Entry<? extends E> entry2 = iterator2.next();
565 E element = entry2.getElement();
566 if (!multiset1.contains(element)) {
567 return immutableEntry(element, entry2.getCount());
568 }
569 }
570 return endOfData();
571 }
572 };
573 }
574
575 @Override
576 int distinctElements() {
577 return elementSet().size();
578 }
579 };
580 }
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 @Beta
598 public static <E> Multiset<E> difference(
599 final Multiset<E> multiset1, final Multiset<?> multiset2) {
600 checkNotNull(multiset1);
601 checkNotNull(multiset2);
602
603
604 return new AbstractMultiset<E>() {
605 @Override
606 public int count(@Nullable Object element) {
607 int count1 = multiset1.count(element);
608 return (count1 == 0) ? 0 :
609 Math.max(0, count1 - multiset2.count(element));
610 }
611
612 @Override
613 Iterator<Entry<E>> entryIterator() {
614 final Iterator<Entry<E>> iterator1 = multiset1.entrySet().iterator();
615 return new AbstractIterator<Entry<E>>() {
616 @Override
617 protected Entry<E> computeNext() {
618 while (iterator1.hasNext()) {
619 Entry<E> entry1 = iterator1.next();
620 E element = entry1.getElement();
621 int count = entry1.getCount() - multiset2.count(element);
622 if (count > 0) {
623 return immutableEntry(element, count);
624 }
625 }
626 return endOfData();
627 }
628 };
629 }
630
631 @Override
632 int distinctElements() {
633 return Iterators.size(entryIterator());
634 }
635 };
636 }
637
638
639
640
641
642
643
644 public static boolean containsOccurrences(
645 Multiset<?> superMultiset, Multiset<?> subMultiset) {
646 checkNotNull(superMultiset);
647 checkNotNull(subMultiset);
648 for (Entry<?> entry : subMultiset.entrySet()) {
649 int superCount = superMultiset.count(entry.getElement());
650 if (superCount < entry.getCount()) {
651 return false;
652 }
653 }
654 return true;
655 }
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676 public static boolean retainOccurrences(Multiset<?> multisetToModify,
677 Multiset<?> multisetToRetain) {
678 return retainOccurrencesImpl(multisetToModify, multisetToRetain);
679 }
680
681
682
683
684 private static <E> boolean retainOccurrencesImpl(
685 Multiset<E> multisetToModify, Multiset<?> occurrencesToRetain) {
686 checkNotNull(multisetToModify);
687 checkNotNull(occurrencesToRetain);
688
689 Iterator<Entry<E>> entryIterator = multisetToModify.entrySet().iterator();
690 boolean changed = false;
691 while (entryIterator.hasNext()) {
692 Entry<E> entry = entryIterator.next();
693 int retainCount = occurrencesToRetain.count(entry.getElement());
694 if (retainCount == 0) {
695 entryIterator.remove();
696 changed = true;
697 } else if (retainCount < entry.getCount()) {
698 multisetToModify.setCount(entry.getElement(), retainCount);
699 changed = true;
700 }
701 }
702 return changed;
703 }
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728 public static boolean removeOccurrences(
729 Multiset<?> multisetToModify, Multiset<?> occurrencesToRemove) {
730 return removeOccurrencesImpl(multisetToModify, occurrencesToRemove);
731 }
732
733
734
735
736 private static <E> boolean removeOccurrencesImpl(
737 Multiset<E> multisetToModify, Multiset<?> occurrencesToRemove) {
738
739 checkNotNull(multisetToModify);
740 checkNotNull(occurrencesToRemove);
741
742 boolean changed = false;
743 Iterator<Entry<E>> entryIterator = multisetToModify.entrySet().iterator();
744 while (entryIterator.hasNext()) {
745 Entry<E> entry = entryIterator.next();
746 int removeCount = occurrencesToRemove.count(entry.getElement());
747 if (removeCount >= entry.getCount()) {
748 entryIterator.remove();
749 changed = true;
750 } else if (removeCount > 0) {
751 multisetToModify.remove(entry.getElement(), removeCount);
752 changed = true;
753 }
754 }
755 return changed;
756 }
757
758
759
760
761
762 abstract static class AbstractEntry<E> implements Multiset.Entry<E> {
763
764
765
766
767 @Override public boolean equals(@Nullable Object object) {
768 if (object instanceof Multiset.Entry) {
769 Multiset.Entry<?> that = (Multiset.Entry<?>) object;
770 return this.getCount() == that.getCount()
771 && Objects.equal(this.getElement(), that.getElement());
772 }
773 return false;
774 }
775
776
777
778
779
780 @Override public int hashCode() {
781 E e = getElement();
782 return ((e == null) ? 0 : e.hashCode()) ^ getCount();
783 }
784
785
786
787
788
789
790
791
792 @Override public String toString() {
793 String text = String.valueOf(getElement());
794 int n = getCount();
795 return (n == 1) ? text : (text + " x " + n);
796 }
797 }
798
799
800
801
802 static boolean equalsImpl(Multiset<?> multiset, @Nullable Object object) {
803 if (object == multiset) {
804 return true;
805 }
806 if (object instanceof Multiset) {
807 Multiset<?> that = (Multiset<?>) object;
808
809
810
811
812
813
814 if (multiset.size() != that.size()
815 || multiset.entrySet().size() != that.entrySet().size()) {
816 return false;
817 }
818 for (Entry<?> entry : that.entrySet()) {
819 if (multiset.count(entry.getElement()) != entry.getCount()) {
820 return false;
821 }
822 }
823 return true;
824 }
825 return false;
826 }
827
828
829
830
831 static <E> boolean addAllImpl(
832 Multiset<E> self, Collection<? extends E> elements) {
833 if (elements.isEmpty()) {
834 return false;
835 }
836 if (elements instanceof Multiset) {
837 Multiset<? extends E> that = cast(elements);
838 for (Entry<? extends E> entry : that.entrySet()) {
839 self.add(entry.getElement(), entry.getCount());
840 }
841 } else {
842 Iterators.addAll(self, elements.iterator());
843 }
844 return true;
845 }
846
847
848
849
850 static boolean removeAllImpl(
851 Multiset<?> self, Collection<?> elementsToRemove) {
852 Collection<?> collection = (elementsToRemove instanceof Multiset)
853 ? ((Multiset<?>) elementsToRemove).elementSet() : elementsToRemove;
854
855 return self.elementSet().removeAll(collection);
856 }
857
858
859
860
861 static boolean retainAllImpl(
862 Multiset<?> self, Collection<?> elementsToRetain) {
863 checkNotNull(elementsToRetain);
864 Collection<?> collection = (elementsToRetain instanceof Multiset)
865 ? ((Multiset<?>) elementsToRetain).elementSet() : elementsToRetain;
866
867 return self.elementSet().retainAll(collection);
868 }
869
870
871
872
873 static <E> int setCountImpl(Multiset<E> self, E element, int count) {
874 checkNonnegative(count, "count");
875
876 int oldCount = self.count(element);
877
878 int delta = count - oldCount;
879 if (delta > 0) {
880 self.add(element, delta);
881 } else if (delta < 0) {
882 self.remove(element, -delta);
883 }
884
885 return oldCount;
886 }
887
888
889
890
891 static <E> boolean setCountImpl(
892 Multiset<E> self, E element, int oldCount, int newCount) {
893 checkNonnegative(oldCount, "oldCount");
894 checkNonnegative(newCount, "newCount");
895
896 if (self.count(element) == oldCount) {
897 self.setCount(element, newCount);
898 return true;
899 } else {
900 return false;
901 }
902 }
903
904 abstract static class ElementSet<E> extends Sets.ImprovedAbstractSet<E> {
905 abstract Multiset<E> multiset();
906
907 @Override public void clear() {
908 multiset().clear();
909 }
910
911 @Override public boolean contains(Object o) {
912 return multiset().contains(o);
913 }
914
915 @Override public boolean containsAll(Collection<?> c) {
916 return multiset().containsAll(c);
917 }
918
919 @Override public boolean isEmpty() {
920 return multiset().isEmpty();
921 }
922
923 @Override public Iterator<E> iterator() {
924 return new TransformedIterator<Entry<E>, E>(multiset().entrySet().iterator()) {
925 @Override
926 E transform(Entry<E> entry) {
927 return entry.getElement();
928 }
929 };
930 }
931
932 @Override
933 public boolean remove(Object o) {
934 int count = multiset().count(o);
935 if (count > 0) {
936 multiset().remove(o, count);
937 return true;
938 }
939 return false;
940 }
941
942 @Override public int size() {
943 return multiset().entrySet().size();
944 }
945 }
946
947 abstract static class EntrySet<E> extends Sets.ImprovedAbstractSet<Entry<E>> {
948 abstract Multiset<E> multiset();
949
950 @Override public boolean contains(@Nullable Object o) {
951 if (o instanceof Entry) {
952
953
954
955 @SuppressWarnings("cast")
956 Entry<?> entry = (Entry<?>) o;
957 if (entry.getCount() <= 0) {
958 return false;
959 }
960 int count = multiset().count(entry.getElement());
961 return count == entry.getCount();
962
963 }
964 return false;
965 }
966
967
968 @SuppressWarnings("cast")
969 @Override public boolean remove(Object object) {
970 if (object instanceof Multiset.Entry) {
971 Entry<?> entry = (Entry<?>) object;
972 Object element = entry.getElement();
973 int entryCount = entry.getCount();
974 if (entryCount != 0) {
975
976 @SuppressWarnings("unchecked")
977 Multiset<Object> multiset = (Multiset) multiset();
978 return multiset.setCount(element, entryCount, 0);
979 }
980 }
981 return false;
982 }
983
984 @Override public void clear() {
985 multiset().clear();
986 }
987 }
988
989
990
991
992 static <E> Iterator<E> iteratorImpl(Multiset<E> multiset) {
993 return new MultisetIteratorImpl<E>(
994 multiset, multiset.entrySet().iterator());
995 }
996
997 static final class MultisetIteratorImpl<E> implements Iterator<E> {
998 private final Multiset<E> multiset;
999 private final Iterator<Entry<E>> entryIterator;
1000 private Entry<E> currentEntry;
1001
1002 private int laterCount;
1003
1004 private int totalCount;
1005 private boolean canRemove;
1006
1007 MultisetIteratorImpl(
1008 Multiset<E> multiset, Iterator<Entry<E>> entryIterator) {
1009 this.multiset = multiset;
1010 this.entryIterator = entryIterator;
1011 }
1012
1013 @Override
1014 public boolean hasNext() {
1015 return laterCount > 0 || entryIterator.hasNext();
1016 }
1017
1018 @Override
1019 public E next() {
1020 if (!hasNext()) {
1021 throw new NoSuchElementException();
1022 }
1023 if (laterCount == 0) {
1024 currentEntry = entryIterator.next();
1025 totalCount = laterCount = currentEntry.getCount();
1026 }
1027 laterCount--;
1028 canRemove = true;
1029 return currentEntry.getElement();
1030 }
1031
1032 @Override
1033 public void remove() {
1034 checkRemove(canRemove);
1035 if (totalCount == 1) {
1036 entryIterator.remove();
1037 } else {
1038 multiset.remove(currentEntry.getElement());
1039 }
1040 totalCount--;
1041 canRemove = false;
1042 }
1043 }
1044
1045
1046
1047
1048 static int sizeImpl(Multiset<?> multiset) {
1049 long size = 0;
1050 for (Entry<?> entry : multiset.entrySet()) {
1051 size += entry.getCount();
1052 }
1053 return Ints.saturatedCast(size);
1054 }
1055
1056
1057
1058
1059 static <T> Multiset<T> cast(Iterable<T> iterable) {
1060 return (Multiset<T>) iterable;
1061 }
1062
1063 private static final Ordering<Entry<?>> DECREASING_COUNT_ORDERING = new Ordering<Entry<?>>() {
1064 @Override
1065 public int compare(Entry<?> entry1, Entry<?> entry2) {
1066 return Ints.compare(entry2.getCount(), entry1.getCount());
1067 }
1068 };
1069
1070
1071
1072
1073
1074
1075
1076 @Beta
1077 public static <E> ImmutableMultiset<E> copyHighestCountFirst(Multiset<E> multiset) {
1078 List<Entry<E>> sortedEntries =
1079 Multisets.DECREASING_COUNT_ORDERING.immutableSortedCopy(multiset.entrySet());
1080 return ImmutableMultiset.copyFromEntries(sortedEntries);
1081 }
1082 }