1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package com.google.common.collect;
16
17 import static com.google.common.base.Preconditions.checkArgument;
18
19 import com.google.common.annotations.GwtCompatible;
20
21 import junit.framework.TestCase;
22
23 import java.io.Serializable;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.concurrent.atomic.AtomicInteger;
27
28 import javax.annotation.Nullable;
29
30
31
32
33
34
35
36 @SuppressWarnings("serial")
37 @GwtCompatible(emulated = true)
38 public class SimpleAbstractMultisetTest extends TestCase {
39
40 public void testFastAddAllMultiset() {
41 final AtomicInteger addCalls = new AtomicInteger();
42 Multiset<String> multiset = new NoRemoveMultiset<String>() {
43 @Override
44 public int add(String element, int occurrences) {
45 addCalls.incrementAndGet();
46 return super.add(element, occurrences);
47 }
48 };
49 ImmutableMultiset<String> adds =
50 new ImmutableMultiset.Builder<String>().addCopies("x", 10).build();
51 multiset.addAll(adds);
52 assertEquals(addCalls.get(), 1);
53 }
54
55 public void testRemoveUnsupported() {
56 Multiset<String> multiset = new NoRemoveMultiset<String>();
57 multiset.add("a");
58 try {
59 multiset.remove("a");
60 fail();
61 } catch (UnsupportedOperationException expected) {}
62 assertTrue(multiset.contains("a"));
63 }
64
65 private static class NoRemoveMultiset<E> extends AbstractMultiset<E>
66 implements Serializable {
67 final Map<E, Integer> backingMap = Maps.newHashMap();
68
69 @Override public int add(@Nullable E element, int occurrences) {
70 checkArgument(occurrences >= 0);
71 Integer frequency = backingMap.get(element);
72 if (frequency == null) {
73 frequency = 0;
74 }
75 if (occurrences == 0) {
76 return frequency;
77 }
78 checkArgument(occurrences <= Integer.MAX_VALUE - frequency);
79 backingMap.put(element, frequency + occurrences);
80 return frequency;
81 }
82
83 @Override
84 Iterator<Entry<E>> entryIterator() {
85 final Iterator<Map.Entry<E, Integer>> backingEntries = backingMap.entrySet().iterator();
86 return new UnmodifiableIterator<Multiset.Entry<E>>() {
87 @Override
88 public boolean hasNext() {
89 return backingEntries.hasNext();
90 }
91
92 @Override
93 public Multiset.Entry<E> next() {
94 final Map.Entry<E, Integer> mapEntry = backingEntries.next();
95 return new Multisets.AbstractEntry<E>() {
96 @Override
97 public E getElement() {
98 return mapEntry.getKey();
99 }
100
101 @Override
102 public int getCount() {
103 Integer frequency = backingMap.get(getElement());
104 return (frequency == null) ? 0 : frequency;
105 }
106 };
107 }
108 };
109 }
110
111 @Override
112 int distinctElements() {
113 return backingMap.size();
114 }
115 }
116 }
117