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;
18  
19  import org.apache.commons.collections4.multiset.HashMultiSet;
20  import org.apache.commons.collections4.multiset.PredicatedMultiSet;
21  import org.apache.commons.collections4.multiset.SynchronizedMultiSet;
22  import org.apache.commons.collections4.multiset.UnmodifiableMultiSet;
23  
24  /**
25   * Provides utility methods and decorators for {@link MultiSet} instances.
26   *
27   * @since 4.1
28   */
29  public class MultiSetUtils {
30  
31      /**
32       * An empty unmodifiable multiset.
33       */
34      @SuppressWarnings("rawtypes") // OK, empty multiset is compatible with any type
35      public static final MultiSet EMPTY_MULTISET =
36          UnmodifiableMultiSet.unmodifiableMultiSet(new HashMultiSet<>());
37  
38      /**
39       * Gets an empty {@code MultiSet}.
40       *
41       * @param <E> the element type
42       * @return an empty MultiSet
43       */
44      @SuppressWarnings("unchecked") // OK, empty multiset is compatible with any type
45      public static <E> MultiSet<E> emptyMultiSet() {
46          return EMPTY_MULTISET;
47      }
48  
49      /**
50       * Returns a predicated (validating) multiset backed by the given multiset.
51       * <p>
52       * Only objects that pass the test in the given predicate can be added to
53       * the multiset. Trying to add an invalid object results in an
54       * IllegalArgumentException. It is important not to use the original multiset
55       * after invoking this method, as it is a backdoor for adding invalid
56       * objects.
57       *
58       * @param <E> the element type
59       * @param multiset the multiset to predicate, must not be null
60       * @param predicate the predicate for the multiset, must not be null
61       * @return a predicated multiset backed by the given multiset
62       * @throws NullPointerException if the MultiSet or Predicate is null
63       */
64      public static <E> MultiSet<E> predicatedMultiSet(final MultiSet<E> multiset,
65              final Predicate<? super E> predicate) {
66          return PredicatedMultiSet.predicatedMultiSet(multiset, predicate);
67      }
68  
69      /**
70       * Returns a synchronized (thread-safe) multiset backed by the given multiset.
71       * In order to guarantee serial access, it is critical that all access to the
72       * backing multiset is accomplished through the returned multiset.
73       * <p>
74       * It is imperative that the user manually synchronize on the returned multiset
75       * when iterating over it:
76       *
77       * <pre>
78       * MultiSet multiset = MultiSetUtils.synchronizedMultiSet(new HashMultiSet());
79       * ...
80       * synchronized(multiset) {
81       *     Iterator i = multiset.iterator(); // Must be in synchronized block
82       *     while (i.hasNext())
83       *         foo(i.next());
84       *     }
85       * }
86       * </pre>
87       *
88       * Failure to follow this advice may result in non-deterministic behavior.
89       *
90       * @param <E> the element type
91       * @param multiset the multiset to synchronize, must not be null
92       * @return a synchronized multiset backed by that multiset
93       * @throws NullPointerException if the MultiSet is null
94       */
95      public static <E> MultiSet<E> synchronizedMultiSet(final MultiSet<E> multiset) {
96          return SynchronizedMultiSet.synchronizedMultiSet(multiset);
97      }
98  
99      /**
100      * Returns an unmodifiable view of the given multiset. Any modification attempts
101      * to the returned multiset will raise an {@link UnsupportedOperationException}.
102      *
103      * @param <E> the element type
104      * @param multiset the multiset whose unmodifiable view is to be returned, must not be null
105      * @return an unmodifiable view of that multiset
106      * @throws NullPointerException if the MultiSet is null
107      */
108     public static <E> MultiSet<E> unmodifiableMultiSet(final MultiSet<? extends E> multiset) {
109         return UnmodifiableMultiSet.unmodifiableMultiSet(multiset);
110     }
111 
112     /**
113      * Don't allow instances.
114      */
115     private MultiSetUtils() {}
116 
117 }