View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.multiset;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.io.IOException;
25  import java.io.Serializable;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Collection;
29  import java.util.ConcurrentModificationException;
30  import java.util.HashSet;
31  import java.util.Iterator;
32  import java.util.List;
33  import java.util.NoSuchElementException;
34  import java.util.Set;
35  
36  import org.apache.commons.collections4.BulkTest;
37  import org.apache.commons.collections4.MultiSet;
38  import org.apache.commons.collections4.collection.AbstractCollectionTest;
39  import org.apache.commons.collections4.set.AbstractSetTest;
40  import org.apache.commons.lang3.ArrayUtils;
41  import org.junit.jupiter.api.Test;
42  
43  /**
44   * Abstract test class for {@link org.apache.commons.collections4.MultiSet MultiSet}
45   * methods and contracts.
46   * <p>
47   * To use, simply extend this class, and implement
48   * the {@link #makeObject} method.
49   * <p>
50   * If your multiset fails one of these tests by design,
51   * you may still use this base set of cases.  Simply override the
52   * test case (method) your multiset fails.
53   * <p>
54   * This abstract test class does wrap the concrete multiset implementation
55   * with such a decorator, see the overridden {@link #resetEmpty()} and
56   * {@link #resetFull()} methods.
57   * <p>
58   * In addition to the generic collection tests (prefix testCollection) inherited
59   * from AbstractCollectionTest, there are test methods that test the "normal" MultiSet
60   * interface (prefix testMultiSet). For MultiSet specific tests use the {@link #makeObject()} and
61   * {@link #makeFullCollection()} methods instead of {@link #resetEmpty()} and resetFull().
62   */
63  public abstract class AbstractMultiSetTest<T> extends AbstractCollectionTest<T> {
64  
65      public class TestMultiSetUniqueSet extends AbstractSetTest<T> {
66  
67          @Override
68          public T[] getFullElements() {
69              return AbstractMultiSetTest.this.getFullElements();
70          }
71  
72          @Override
73          protected int getIterationBehaviour() {
74              return AbstractMultiSetTest.this.getIterationBehaviour();
75          }
76  
77          @Override
78          public T[] getOtherElements() {
79              return AbstractMultiSetTest.this.getOtherElements();
80          }
81  
82          @Override
83          public boolean isAddSupported() {
84              return false;
85          }
86  
87          @Override
88          public boolean isNullSupported() {
89              return AbstractMultiSetTest.this.isNullSupported();
90          }
91  
92          @Override
93          public boolean isRemoveSupported() {
94              return AbstractMultiSetTest.this.isRemoveSupported();
95          }
96  
97          @Override
98          public boolean isTestSerialization() {
99              return false;
100         }
101 
102         @Override
103         public Set<T> makeFullCollection() {
104             return AbstractMultiSetTest.this.makeFullCollection().uniqueSet();
105         }
106 
107         @Override
108         public Set<T> makeObject() {
109             return AbstractMultiSetTest.this.makeObject().uniqueSet();
110         }
111 
112         @Override
113         public void resetEmpty() {
114             AbstractMultiSetTest.this.resetEmpty();
115             TestMultiSetUniqueSet.this.setCollection(AbstractMultiSetTest.this.getCollection().uniqueSet());
116             TestMultiSetUniqueSet.this.setConfirmed(new HashSet<>(AbstractMultiSetTest.this.getConfirmed()));
117         }
118 
119         @Override
120         public void resetFull() {
121             AbstractMultiSetTest.this.resetFull();
122             TestMultiSetUniqueSet.this.setCollection(AbstractMultiSetTest.this.getCollection().uniqueSet());
123             TestMultiSetUniqueSet.this.setConfirmed(new HashSet<>(AbstractMultiSetTest.this.getConfirmed()));
124         }
125 
126         @Override
127         public void verify() {
128             super.verify();
129         }
130     }
131 
132     /**
133      * Bulk test {@link MultiSet#uniqueSet()}.  This method runs through all of
134      * the tests in {@link AbstractSetTest}.
135      * After modification operations, {@link #verify()} is invoked to ensure
136      * that the multiset and the other collection views are still valid.
137      *
138      * @return a {@link AbstractSetTest} instance for testing the multiset's unique set
139      */
140     public BulkTest bulkTestMultiSetUniqueSet() {
141         return new TestMultiSetUniqueSet();
142     }
143 
144     /**
145      * Returns the {@link #collection} field cast to a {@link MultiSet}.
146      *
147      * @return the collection field as a MultiSet
148      */
149     @Override
150     public MultiSet<T> getCollection() {
151         return (MultiSet<T>) super.getCollection();
152     }
153 
154     /**
155      * Returns an empty {@link ArrayList}.
156      */
157     @Override
158     public Collection<T> makeConfirmedCollection() {
159         return new ArrayList<>();
160     }
161 
162     /**
163      * Returns a full collection.
164      */
165     @Override
166     public Collection<T> makeConfirmedFullCollection() {
167         final Collection<T> coll = makeConfirmedCollection();
168         coll.addAll(Arrays.asList(getFullElements()));
169         return coll;
170     }
171 
172     /**
173      * {@inheritDoc}
174      */
175     @Override
176     public MultiSet<T> makeFullCollection() {
177         final MultiSet<T> multiset = makeObject();
178         multiset.addAll(Arrays.asList(getFullElements()));
179         return multiset;
180     }
181 
182     /**
183      * Return a new, empty multiset to used for testing.
184      *
185      * @return the multiset to be tested
186      */
187     @Override
188     public abstract MultiSet<T> makeObject();
189 
190     @Override
191     public void resetEmpty() {
192         setCollection(makeObject());
193         setConfirmed(makeConfirmedCollection());
194     }
195 
196     @Override
197     public void resetFull() {
198         setCollection(makeFullCollection());
199         setConfirmed(makeConfirmedFullCollection());
200     }
201 
202     /**
203      * Compare the current serialized form of the MultiSet
204      * against the canonical version in SCM.
205      */
206     @Test
207     public void testEmptyMultiSetCompatibility() throws IOException, ClassNotFoundException {
208         // test to make sure the canonical form has been preserved
209         final MultiSet<T> multiset = makeObject();
210         if (multiset instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
211             final MultiSet<?> multiset2 = (MultiSet<?>) readExternalFormFromDisk(getCanonicalEmptyCollectionName(multiset));
212             assertTrue(multiset2.isEmpty(), "MultiSet is empty");
213             assertEquals(multiset, multiset2);
214         }
215     }
216 
217     /**
218      * Compare the current serialized form of the MultiSet
219      * against the canonical version in SCM.
220      */
221     @Test
222     public void testFullMultiSetCompatibility() throws IOException, ClassNotFoundException {
223         // test to make sure the canonical form has been preserved
224         final MultiSet<T> multiset = makeFullCollection();
225         if (multiset instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
226             final MultiSet<?> multiset2 = (MultiSet<?>) readExternalFormFromDisk(getCanonicalFullCollectionName(multiset));
227             assertEquals(multiset.size(), multiset2.size(), "MultiSet is the right size");
228             assertEquals(multiset, multiset2);
229         }
230     }
231 
232     @Test
233     @SuppressWarnings("unchecked")
234     public void testMultiSetAdd() {
235         if (!isAddSupported()) {
236             return;
237         }
238 
239         final MultiSet<T> multiset = makeObject();
240         multiset.add((T) "A");
241         assertTrue(multiset.contains("A"), "Should contain 'A'");
242         assertEquals(1, multiset.getCount("A"), "Should have count of 1");
243         multiset.add((T) "A");
244         assertTrue(multiset.contains("A"), "Should contain 'A'");
245         assertEquals(2, multiset.getCount("A"), "Should have count of 2");
246         multiset.add((T) "B");
247         assertTrue(multiset.contains("A"));
248         assertTrue(multiset.contains("B"));
249     }
250 
251     @Test
252     @SuppressWarnings("unchecked")
253     public void testMultiSetContains() {
254         if (!isAddSupported()) {
255             return;
256         }
257 
258         final MultiSet<T> multiset = makeObject();
259 
260         assertFalse(multiset.contains("A"), "MultiSet does not have at least 1 'A'");
261         assertFalse(multiset.contains("B"), "MultiSet does not have at least 1 'B'");
262 
263         multiset.add((T) "A");  // multiset 1A
264         assertTrue(multiset.contains("A"), "MultiSet has at least 1 'A'");
265         assertFalse(multiset.contains("B"), "MultiSet does not have at least 1 'B'");
266 
267         multiset.add((T) "A");  // multiset 2A
268         assertTrue(multiset.contains("A"), "MultiSet has at least 1 'A'");
269         assertFalse(multiset.contains("B"), "MultiSet does not have at least 1 'B'");
270 
271         multiset.add((T) "B");  // multiset 2A,1B
272         assertTrue(multiset.contains("A"), "MultiSet has at least 1 'A'");
273         assertTrue(multiset.contains("B"), "MultiSet has at least 1 'B'");
274     }
275 
276     @Test
277     @SuppressWarnings("unchecked")
278     public void testMultiSetContainsAll() {
279         if (!isAddSupported()) {
280             return;
281         }
282 
283         final MultiSet<T> multiset = makeObject();
284         final List<String> known = new ArrayList<>();
285         final List<String> known1A = new ArrayList<>();
286         known1A.add("A");
287         final List<String> known2A = new ArrayList<>();
288         known2A.add("A");
289         known2A.add("A");
290         final List<String> known1B = new ArrayList<>();
291         known1B.add("B");
292         final List<String> known1A1B = new ArrayList<>();
293         known1A1B.add("A");
294         known1A1B.add("B");
295 
296         assertTrue(multiset.containsAll(known), "MultiSet containsAll of empty");
297         assertFalse(multiset.containsAll(known1A), "MultiSet does not containsAll of 1 'A'");
298         assertFalse(multiset.containsAll(known2A), "MultiSet does not containsAll of 2 'A'");
299         assertFalse(multiset.containsAll(known1B), "MultiSet does not containsAll of 1 'B'");
300         assertFalse(multiset.containsAll(known1A1B), "MultiSet does not containsAll of 1 'A' 1 'B'");
301 
302         multiset.add((T) "A");  // multiset 1A
303         assertTrue(multiset.containsAll(known), "MultiSet containsAll of empty");
304         assertTrue(multiset.containsAll(known1A), "MultiSet containsAll of 1 'A'");
305         assertTrue(multiset.containsAll(known2A), "MultiSet does not containsAll 'A'");
306         assertFalse(multiset.containsAll(known1B), "MultiSet does not containsAll of 1 'B'");
307         assertFalse(multiset.containsAll(known1A1B), "MultiSet does not containsAll of 1 'A' 1 'B'");
308 
309         multiset.add((T) "A");  // multiset 2A
310         assertTrue(multiset.containsAll(known), "MultiSet containsAll of empty");
311         assertTrue(multiset.containsAll(known1A), "MultiSet containsAll of 1 'A'");
312         assertTrue(multiset.containsAll(known2A), "MultiSet containsAll of 2 'A'");
313         assertFalse(multiset.containsAll(known1B), "MultiSet does not containsAll of 1 'B'");
314         assertFalse(multiset.containsAll(known1A1B), "MultiSet does not containsAll of 1 'A' 1 'B'");
315 
316         multiset.add((T) "A");  // multiset 3A
317         assertTrue(multiset.containsAll(known), "MultiSet containsAll of empty");
318         assertTrue(multiset.containsAll(known1A), "MultiSet containsAll of 1 'A'");
319         assertTrue(multiset.containsAll(known2A), "MultiSet containsAll of 2 'A'");
320         assertFalse(multiset.containsAll(known1B), "MultiSet does not containsAll of 1 'B'");
321         assertFalse(multiset.containsAll(known1A1B), "MultiSet does not containsAll of 1 'A' 1 'B'");
322 
323         multiset.add((T) "B");  // multiset 3A1B
324         assertTrue(multiset.containsAll(known), "MultiSet containsAll of empty");
325         assertTrue(multiset.containsAll(known1A), "MultiSet containsAll of 1 'A'");
326         assertTrue(multiset.containsAll(known2A), "MultiSet containsAll of 2 'A'");
327         assertTrue(multiset.containsAll(known1B), "MultiSet containsAll of 1 'B'");
328         assertTrue(multiset.containsAll(known1A1B), "MultiSet containsAll of 1 'A' 1 'B'");
329     }
330 
331     @Test
332     @SuppressWarnings("unchecked")
333     public void testMultiSetEntrySetUpdatedToZero() {
334         if (!isAddSupported()) {
335             return;
336         }
337         final MultiSet<T> multiset = makeObject();
338         multiset.add((T) "A");
339         multiset.add((T) "A");
340         final MultiSet.Entry<T> entry = multiset.entrySet().iterator().next();
341         assertEquals(2, entry.getCount());
342         multiset.remove("A");
343         assertEquals(1, entry.getCount());
344         multiset.remove("A");
345         assertEquals(0, entry.getCount());
346     }
347 
348     @Test
349     @SuppressWarnings("unchecked")
350     public void testMultiSetEquals() {
351         if (!isAddSupported()) {
352             return;
353         }
354 
355         final MultiSet<T> multiset = makeObject();
356         final MultiSet<T> multiset2 = makeObject();
357         assertTrue(multiset.equals(multiset2));
358         multiset.add((T) "A");
359         assertFalse(multiset.equals(multiset2));
360         multiset2.add((T) "A");
361         assertTrue(multiset.equals(multiset2));
362         multiset.add((T) "A");
363         multiset.add((T) "B");
364         multiset.add((T) "B");
365         multiset.add((T) "C");
366         multiset2.add((T) "A");
367         multiset2.add((T) "B");
368         multiset2.add((T) "B");
369         multiset2.add((T) "C");
370         assertTrue(multiset.equals(multiset2));
371     }
372 
373     @Test
374     @SuppressWarnings("unchecked")
375     public void testMultiSetEqualsHashMultiSet() {
376         if (!isAddSupported()) {
377             return;
378         }
379 
380         final MultiSet<T> multiset = makeObject();
381         final MultiSet<T> multiset2 = new HashMultiSet<>();
382         assertTrue(multiset.equals(multiset2));
383         multiset.add((T) "A");
384         assertFalse(multiset.equals(multiset2));
385         multiset2.add((T) "A");
386         assertTrue(multiset.equals(multiset2));
387         multiset.add((T) "A");
388         multiset.add((T) "B");
389         multiset.add((T) "B");
390         multiset.add((T) "C");
391         multiset2.add((T) "A");
392         multiset2.add((T) "B");
393         multiset2.add((T) "B");
394         multiset2.add((T) "C");
395         assertTrue(multiset.equals(multiset2));
396     }
397 
398     @Test
399     @SuppressWarnings("unchecked")
400     public void testMultiSetEqualsSelf() {
401         final MultiSet<T> multiset = makeObject();
402         assertEquals(multiset, multiset);
403 
404         if (!isAddSupported()) {
405             return;
406         }
407 
408         multiset.add((T) "elt");
409         assertEquals(multiset, multiset);
410         multiset.add((T) "elt"); // again
411         assertEquals(multiset, multiset);
412         multiset.add((T) "elt2");
413         assertEquals(multiset, multiset);
414     }
415 
416     @Test
417     @SuppressWarnings("unchecked")
418     public void testMultiSetHashCode() {
419         if (!isAddSupported()) {
420             return;
421         }
422 
423         final MultiSet<T> multiset = makeObject();
424         final MultiSet<T> multiset2 = makeObject();
425         assertEquals(0, multiset.hashCode());
426         assertEquals(0, multiset2.hashCode());
427         assertEquals(multiset.hashCode(), multiset2.hashCode());
428         multiset.add((T) "A");
429         multiset.add((T) "A");
430         multiset.add((T) "B");
431         multiset.add((T) "B");
432         multiset.add((T) "C");
433         multiset2.add((T) "A");
434         multiset2.add((T) "A");
435         multiset2.add((T) "B");
436         multiset2.add((T) "B");
437         multiset2.add((T) "C");
438         assertEquals(multiset.hashCode(), multiset2.hashCode());
439 
440         int total = 0;
441         total += "A".hashCode() ^ 2;
442         total += "B".hashCode() ^ 2;
443         total += "C".hashCode() ^ 1;
444         assertEquals(total, multiset.hashCode());
445         assertEquals(total, multiset2.hashCode());
446     }
447 
448     @Test
449     @SuppressWarnings("unchecked")
450     public void testMultiSetIterator() {
451         if (!isAddSupported()) {
452             return;
453         }
454 
455         final MultiSet<T> multiset = makeObject();
456         multiset.add((T) "A");
457         multiset.add((T) "A");
458         multiset.add((T) "B");
459         assertEquals(3, multiset.size(), "MultiSet should have 3 items");
460         final Iterator<T> i = multiset.iterator();
461 
462         boolean foundA = false;
463         while (i.hasNext()) {
464             final String element = (String) i.next();
465             // ignore the first A, remove the second via Iterator.remove()
466             if (element.equals("A")) {
467                 if (!foundA) {
468                     foundA = true;
469                 } else {
470                     i.remove();
471                 }
472             }
473         }
474 
475         assertTrue(multiset.contains("A"), "MultiSet should still contain 'A'");
476         assertEquals(2, multiset.size(), "MultiSet should have 2 items");
477         assertEquals(1, multiset.getCount("A"), "MultiSet should have 1 'A'");
478     }
479 
480     @Test
481     @SuppressWarnings("unchecked")
482     public void testMultiSetIteratorFail() {
483         if (!isAddSupported()) {
484             return;
485         }
486 
487         final MultiSet<T> multiset = makeObject();
488         multiset.add((T) "A");
489         multiset.add((T) "A");
490         multiset.add((T) "B");
491         final Iterator<T> it = multiset.iterator();
492         it.next();
493         multiset.remove("A");
494         assertThrows(ConcurrentModificationException.class, () -> it.next(),
495                 "Should throw ConcurrentModificationException");
496     }
497 
498     @Test
499     @SuppressWarnings("unchecked")
500     public void testMultiSetIteratorFailDoubleRemove() {
501         if (!isAddSupported()) {
502             return;
503         }
504 
505         final MultiSet<T> multiset = makeObject();
506         multiset.add((T) "A");
507         multiset.add((T) "A");
508         multiset.add((T) "B");
509         final Iterator<T> it = multiset.iterator();
510         it.next();
511         it.next();
512         assertEquals(3, multiset.size());
513         it.remove();
514         assertEquals(2, multiset.size());
515         assertThrows(IllegalStateException.class, () -> it.remove(),
516                 "Should throw IllegalStateException");
517         assertEquals(2, multiset.size());
518         it.next();
519         it.remove();
520         assertEquals(1, multiset.size());
521     }
522 
523     @Test
524     @SuppressWarnings("unchecked")
525     public void testMultiSetIteratorFailNoMore() {
526         if (!isAddSupported()) {
527             return;
528         }
529 
530         final MultiSet<T> multiset = makeObject();
531         multiset.add((T) "A");
532         multiset.add((T) "A");
533         multiset.add((T) "B");
534         final Iterator<T> it = multiset.iterator();
535         it.next();
536         it.next();
537         it.next();
538         assertThrows(NoSuchElementException.class, () -> it.next(),
539                 "Should throw NoSuchElementException");
540     }
541 
542     @Test
543     @SuppressWarnings("unchecked")
544     public void testMultiSetIteratorRemoveProtectsInvariants() {
545         if (!isAddSupported()) {
546             return;
547         }
548 
549         final MultiSet<T> multiset = makeObject();
550         multiset.add((T) "A");
551         multiset.add((T) "A");
552         assertEquals(2, multiset.size());
553         final Iterator<T> it = multiset.iterator();
554         assertEquals("A", it.next());
555         assertTrue(it.hasNext());
556         it.remove();
557         assertEquals(1, multiset.size());
558         assertTrue(it.hasNext());
559         assertEquals("A", it.next());
560         assertFalse(it.hasNext());
561         it.remove();
562         assertEquals(0, multiset.size());
563         assertFalse(it.hasNext());
564 
565         final Iterator<T> it2 = multiset.iterator();
566         assertFalse(it2.hasNext());
567     }
568 
569     @Test
570     @SuppressWarnings("unchecked")
571     public void testMultiSetRemove() {
572         if (!isRemoveSupported()) {
573             return;
574         }
575 
576         final MultiSet<T> multiset = makeObject();
577         multiset.add((T) "A");
578         assertEquals(1, multiset.getCount("A"), "Should have count of 1");
579         multiset.remove("A");
580         assertEquals(0, multiset.getCount("A"), "Should have count of 0");
581         multiset.add((T) "A");
582         multiset.add((T) "A");
583         multiset.add((T) "A");
584         multiset.add((T) "A");
585         assertEquals(4, multiset.getCount("A"), "Should have count of 4");
586         multiset.remove("A", 0);
587         assertEquals(4, multiset.getCount("A"), "Should have count of 4");
588         multiset.remove("A", 2);
589         assertEquals(2, multiset.getCount("A"), "Should have count of 2");
590         multiset.remove("A");
591         assertEquals(1, multiset.getCount("A"), "Should have count of 1");
592     }
593 
594     @Test
595     @SuppressWarnings("unchecked")
596     public void testMultiSetRemoveAll() {
597         if (!isRemoveSupported()) {
598             return;
599         }
600 
601         final MultiSet<T> multiset = makeObject();
602         multiset.add((T) "A", 2);
603         assertEquals(2, multiset.getCount("A"), "Should have count of 2");
604         multiset.add((T) "B");
605         multiset.add((T) "C");
606         assertEquals(4, multiset.size(), "Should have count of 4");
607         final List<String> delete = new ArrayList<>();
608         delete.add("A");
609         delete.add("B");
610         multiset.removeAll(delete);
611         assertEquals(0, multiset.getCount("A"), "Should have count of 0");
612         assertEquals(0, multiset.getCount("B"), "Should have count of 0");
613         assertEquals(1, multiset.getCount("C"), "Should have count of 1");
614         assertEquals(1, multiset.size(), "Should have count of 1");
615     }
616 
617     @Test
618     @SuppressWarnings("unchecked")
619     public void testMultiSetRetainAll() {
620         if (!isAddSupported()) {
621             return;
622         }
623 
624         final MultiSet<T> multiset = makeObject();
625         multiset.add((T) "A");
626         multiset.add((T) "A");
627         multiset.add((T) "A");
628         multiset.add((T) "B");
629         multiset.add((T) "B");
630         multiset.add((T) "C");
631         final List<String> retains = new ArrayList<>();
632         retains.add("B");
633         retains.add("C");
634         multiset.retainAll(retains);
635         assertEquals(3, multiset.size(), "Should have 3 total items");
636     }
637 
638     @Test
639     @SuppressWarnings("unchecked")
640     public void testMultiSetSize() {
641         if (!isAddSupported()) {
642             return;
643         }
644 
645         final MultiSet<T> multiset = makeObject();
646         assertEquals(0, multiset.size(), "Should have 0 total items");
647         multiset.add((T) "A");
648         assertEquals(1, multiset.size(), "Should have 1 total items");
649         multiset.add((T) "A");
650         assertEquals(2, multiset.size(), "Should have 2 total items");
651         multiset.add((T) "A");
652         assertEquals(3, multiset.size(), "Should have 3 total items");
653         multiset.add((T) "B");
654         assertEquals(4, multiset.size(), "Should have 4 total items");
655         multiset.add((T) "B");
656         assertEquals(5, multiset.size(), "Should have 5 total items");
657         multiset.remove("A", 2);
658         assertEquals(1, multiset.getCount("A"), "Should have 1 'A'");
659         assertEquals(3, multiset.size(), "Should have 3 total items");
660         multiset.remove("B");
661         assertEquals(2, multiset.size(), "Should have 2 total item");
662     }
663 
664     @Test
665     @SuppressWarnings("unchecked")
666     public void testMultiSetToArray() {
667         if (!isAddSupported()) {
668             return;
669         }
670 
671         final MultiSet<T> multiset = makeObject();
672         multiset.add((T) "A");
673         multiset.add((T) "A");
674         multiset.add((T) "B");
675         multiset.add((T) "B");
676         multiset.add((T) "C");
677         final Object[] array = multiset.toArray();
678         int a = 0;
679         int b = 0;
680         int c = 0;
681         for (final Object element : array) {
682             a += element.equals("A") ? 1 : 0;
683             b += element.equals("B") ? 1 : 0;
684             c += element.equals("C") ? 1 : 0;
685         }
686         assertEquals(2, a);
687         assertEquals(2, b);
688         assertEquals(1, c);
689     }
690 
691     @Test
692     @SuppressWarnings("unchecked")
693     public void testMultiSetToArrayPopulate() {
694         if (!isAddSupported()) {
695             return;
696         }
697 
698         final MultiSet<T> multiset = makeObject();
699         multiset.add((T) "A");
700         multiset.add((T) "A");
701         multiset.add((T) "B");
702         multiset.add((T) "B");
703         multiset.add((T) "C");
704         final String[] array = multiset.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
705         int a = 0;
706         int b = 0;
707         int c = 0;
708         for (final String element : array) {
709             a += element.equals("A") ? 1 : 0;
710             b += element.equals("B") ? 1 : 0;
711             c += element.equals("C") ? 1 : 0;
712         }
713         assertEquals(2, a);
714         assertEquals(2, b);
715         assertEquals(1, c);
716     }
717 
718 }