• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
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 import com.google.common.collect.Multiset.Entry;
21 
22 import java.io.Serializable;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.concurrent.atomic.AtomicInteger;
26 
27 /**
28  * Unit test for {@link AbstractMultiset}.
29  *
30  * @author Kevin Bourrillion
31  * @author Louis Wasserman
32  */
33 @SuppressWarnings("serial") // No serialization is used in this test
34 @GwtCompatible
35 public class SimpleAbstractMultisetTest extends AbstractMultisetTest {
36 
create()37   @Override protected <E> Multiset<E> create() {
38     return new SimpleAbstractMultiset<E>();
39   }
40 
testFastAddAllMultiset()41   public void testFastAddAllMultiset() {
42     final AtomicInteger addCalls = new AtomicInteger();
43     Multiset<String> multiset = new NoRemoveMultiset<String>() {
44       @Override
45       public int add(String element, int occurrences) {
46         addCalls.incrementAndGet();
47         return super.add(element, occurrences);
48       }
49     };
50     ImmutableMultiset<String> adds =
51         new ImmutableMultiset.Builder<String>().addCopies("x", 10).build();
52     multiset.addAll(adds);
53     assertEquals(addCalls.get(), 1);
54   }
55 
testRemoveUnsupported()56   public void testRemoveUnsupported() {
57     Multiset<String> multiset = new NoRemoveMultiset<String>();
58     multiset.add("a");
59     try {
60       multiset.remove("a");
61       fail();
62     } catch (UnsupportedOperationException expected) {}
63     assertTrue(multiset.contains("a"));
64   }
65 
66   private static class NoRemoveMultiset<E> extends AbstractMultiset<E>
67       implements Serializable {
68     final Map<E, Integer> backingMap = Maps.newHashMap();
69 
add(E element, int occurrences)70     @Override public int add(E element, int occurrences) {
71       checkArgument(occurrences >= 0);
72       Integer frequency = backingMap.get(element);
73       if (frequency == null) {
74         frequency = 0;
75       }
76       if (occurrences == 0) {
77         return frequency;
78       }
79       checkArgument(occurrences <= Integer.MAX_VALUE - frequency);
80       backingMap.put(element, frequency + occurrences);
81       return frequency;
82     }
83 
84     @Override
entryIterator()85     Iterator<Entry<E>> entryIterator() {
86       final Iterator<Map.Entry<E, Integer>> backingEntries = backingMap.entrySet().iterator();
87       return new Iterator<Multiset.Entry<E>>() {
88         @Override
89         public boolean hasNext() {
90           return backingEntries.hasNext();
91         }
92 
93         @Override
94         public Multiset.Entry<E> next() {
95           final Map.Entry<E, Integer> mapEntry = backingEntries.next();
96           return new Multisets.AbstractEntry<E>() {
97             @Override
98             public E getElement() {
99               return mapEntry.getKey();
100             }
101 
102             @Override
103             public int getCount() {
104               Integer frequency = backingMap.get(getElement());
105               return (frequency == null) ? 0 : frequency;
106             }
107           };
108         }
109 
110         @Override
111         public void remove() {
112           backingEntries.remove();
113         }
114       };
115     }
116 
117     @Override
118     int distinctElements() {
119       return backingMap.size();
120     }
121   }
122 
123   private static class SimpleAbstractMultiset<E> extends NoRemoveMultiset<E> {
124     @SuppressWarnings("unchecked")
125     @Override public int remove(Object element, int occurrences) {
126       checkArgument(occurrences >= 0);
127       Integer count = backingMap.get(element);
128       if (count == null) {
129         return 0;
130       } else if (count > occurrences) {
131         backingMap.put((E) element, count - occurrences);
132         return count;
133       } else {
134         return backingMap.remove(element);
135       }
136     }
137   }
138 }
139