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 * </p>
58 *
59 * @param <E> the element type
60 * @param multiset the multiset to predicate, must not be null
61 * @param predicate the predicate for the multiset, must not be null
62 * @return a predicated multiset backed by the given multiset
63 * @throws NullPointerException if the MultiSet or Predicate is null
64 */
65 public static <E> MultiSet<E> predicatedMultiSet(final MultiSet<E> multiset,
66 final Predicate<? super E> predicate) {
67 return PredicatedMultiSet.predicatedMultiSet(multiset, predicate);
68 }
69
70 /**
71 * Returns a synchronized (thread-safe) multiset backed by the given multiset.
72 * In order to guarantee serial access, it is critical that all access to the
73 * backing multiset is accomplished through the returned multiset.
74 * <p>
75 * It is imperative that the user manually synchronize on the returned multiset
76 * when iterating over it:
77 * </p>
78 * <pre>
79 * MultiSet multiset = MultiSetUtils.synchronizedMultiSet(new HashMultiSet());
80 * ...
81 * synchronized(multiset) {
82 * Iterator i = multiset.iterator(); // Must be in synchronized block
83 * while (i.hasNext())
84 * foo(i.next());
85 * }
86 * }
87 * </pre>
88 *
89 * Failure to follow this advice may result in non-deterministic behavior.
90 *
91 * @param <E> the element type
92 * @param multiset the multiset to synchronize, must not be null
93 * @return a synchronized multiset backed by that multiset
94 * @throws NullPointerException if the MultiSet is null
95 */
96 public static <E> MultiSet<E> synchronizedMultiSet(final MultiSet<E> multiset) {
97 return SynchronizedMultiSet.synchronizedMultiSet(multiset);
98 }
99
100 /**
101 * Returns an unmodifiable view of the given multiset. Any modification attempts
102 * to the returned multiset will raise an {@link UnsupportedOperationException}.
103 *
104 * @param <E> the element type
105 * @param multiset the multiset whose unmodifiable view is to be returned, must not be null
106 * @return an unmodifiable view of that multiset
107 * @throws NullPointerException if the MultiSet is null
108 */
109 public static <E> MultiSet<E> unmodifiableMultiSet(final MultiSet<? extends E> multiset) {
110 return UnmodifiableMultiSet.unmodifiableMultiSet(multiset);
111 }
112
113 /**
114 * Don't allow instances.
115 */
116 private MultiSetUtils() {
117 // empty
118 }
119
120 }