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    *      https://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.bag.CollectionBag;
20  import org.apache.commons.collections4.bag.HashBag;
21  import org.apache.commons.collections4.bag.PredicatedBag;
22  import org.apache.commons.collections4.bag.PredicatedSortedBag;
23  import org.apache.commons.collections4.bag.SynchronizedBag;
24  import org.apache.commons.collections4.bag.SynchronizedSortedBag;
25  import org.apache.commons.collections4.bag.TransformedBag;
26  import org.apache.commons.collections4.bag.TransformedSortedBag;
27  import org.apache.commons.collections4.bag.TreeBag;
28  import org.apache.commons.collections4.bag.UnmodifiableBag;
29  import org.apache.commons.collections4.bag.UnmodifiableSortedBag;
30  
31  /**
32   * Provides utility methods and decorators for {@link Bag} and {@link SortedBag} instances.
33   *
34   * @since 2.1
35   * @deprecated Since 4.6.0, use {@link MultiSetUtils} instead.
36   */
37  @Deprecated
38  public class BagUtils {
39  
40      /**
41       * An empty unmodifiable bag.
42       */
43      @SuppressWarnings("rawtypes") // OK, empty bag is compatible with any type
44      public static final Bag EMPTY_BAG = UnmodifiableBag.unmodifiableBag(new HashBag<>());
45  
46      /**
47       * An empty unmodifiable sorted bag.
48       */
49      @SuppressWarnings("rawtypes") // OK, empty bag is compatible with any type
50      public static final Bag EMPTY_SORTED_BAG =
51              UnmodifiableSortedBag.unmodifiableSortedBag(new TreeBag<>());
52  
53      /**
54       * Returns a bag that complies to the Collection contract, backed by the given bag.
55       *
56       * @param <E> The element type
57       * @param bag The bag to decorate, must not be null
58       * @return A Bag that complies to the Collection contract
59       * @throws NullPointerException if bag is null
60       * @since 4.0
61       */
62      public static <E> Bag<E> collectionBag(final Bag<E> bag) {
63          return CollectionBag.collectionBag(bag);
64      }
65  
66      /**
67       * Gets an empty {@code Bag}.
68       *
69       * @param <E> The element type
70       * @return An empty Bag
71       */
72      @SuppressWarnings("unchecked") // OK, empty bag is compatible with any type
73      public static <E> Bag<E> emptyBag() {
74          return EMPTY_BAG;
75      }
76  
77      /**
78       * Gets an empty {@code SortedBag}.
79       *
80       * @param <E> The element type
81       * @return An empty sorted Bag
82       */
83      @SuppressWarnings("unchecked") // OK, empty bag is compatible with any type
84      public static <E> SortedBag<E> emptySortedBag() {
85          return (SortedBag<E>) EMPTY_SORTED_BAG;
86      }
87  
88      /**
89       * Returns a predicated (validating) bag backed by the given bag.
90       * <p>
91       * Only objects that pass the test in the given predicate can be added to
92       * the bag. Trying to add an invalid object results in an
93       * IllegalArgumentException. It is important not to use the original bag
94       * after invoking this method, as it is a backdoor for adding invalid
95       * objects.
96       * </p>
97       *
98       * @param <E> The element type
99       * @param bag The bag to predicate, must not be null
100      * @param predicate The predicate for the bag, must not be null
101      * @return A predicated bag backed by the given bag
102      * @throws NullPointerException if the Bag or Predicate is null
103      */
104     public static <E> Bag<E> predicatedBag(final Bag<E> bag, final Predicate<? super E> predicate) {
105         return PredicatedBag.predicatedBag(bag, predicate);
106     }
107 
108     /**
109      * Returns a predicated (validating) sorted bag backed by the given sorted
110      * bag.
111      * <p>
112      * Only objects that pass the test in the given predicate can be added to
113      * the bag. Trying to add an invalid object results in an
114      * IllegalArgumentException. It is important not to use the original bag
115      * after invoking this method, as it is a backdoor for adding invalid
116      * objects.
117      * </p>
118      *
119      * @param <E> The element type
120      * @param bag The sorted bag to predicate, must not be null
121      * @param predicate The predicate for the bag, must not be null
122      * @return A predicated bag backed by the given bag
123      * @throws NullPointerException if the SortedBag or Predicate is null
124      */
125     public static <E> SortedBag<E> predicatedSortedBag(final SortedBag<E> bag,
126             final Predicate<? super E> predicate) {
127         return PredicatedSortedBag.predicatedSortedBag(bag, predicate);
128     }
129 
130     /**
131      * Returns a synchronized (thread-safe) bag backed by the given bag. In
132      * order to guarantee serial access, it is critical that all access to the
133      * backing bag is accomplished through the returned bag.
134      * <p>
135      * It is imperative that the user manually synchronize on the returned bag
136      * when iterating over it:
137      * </p>
138      *
139      * <pre>
140      * Bag bag = BagUtils.synchronizedBag(new HashBag());
141      * ...
142      * synchronized(bag) {
143      *     Iterator i = bag.iterator(); // Must be in synchronized block
144      *     while (i.hasNext())
145      *         foo(i.next());
146      *     }
147      * }
148      * </pre>
149      *
150      * Failure to follow this advice may result in non-deterministic behavior.
151      *
152      * @param <E> The element type
153      * @param bag The bag to synchronize, must not be null
154      * @return A synchronized bag backed by that bag
155      * @throws NullPointerException if the Bag is null
156      */
157     public static <E> Bag<E> synchronizedBag(final Bag<E> bag) {
158         return SynchronizedBag.synchronizedBag(bag);
159     }
160 
161     /**
162      * Returns a synchronized (thread-safe) sorted bag backed by the given
163      * sorted bag. In order to guarantee serial access, it is critical that all
164      * access to the backing bag is accomplished through the returned bag.
165      * <p>
166      * It is imperative that the user manually synchronize on the returned bag
167      * when iterating over it:
168      * </p>
169      *
170      * <pre>
171      * SortedBag bag = BagUtils.synchronizedSortedBag(new TreeBag());
172      * ...
173      * synchronized(bag) {
174      *     Iterator i = bag.iterator(); // Must be in synchronized block
175      *     while (i.hasNext())
176      *         foo(i.next());
177      *     }
178      * }
179      * </pre>
180      *
181      * Failure to follow this advice may result in non-deterministic behavior.
182      *
183      * @param <E> The element type
184      * @param bag The bag to synchronize, must not be null
185      * @return A synchronized bag backed by that bag
186      * @throws NullPointerException if the SortedBag is null
187      */
188     public static <E> SortedBag<E> synchronizedSortedBag(final SortedBag<E> bag) {
189         return SynchronizedSortedBag.synchronizedSortedBag(bag);
190     }
191 
192     /**
193      * Returns a transformed bag backed by the given bag.
194      * <p>
195      * Each object is passed through the transformer as it is added to the Bag.
196      * It is important not to use the original bag after invoking this method,
197      * as it is a backdoor for adding untransformed objects.
198      * </p>
199      * <p>
200      * Existing entries in the specified bag will not be transformed.
201      * If you want that behavior, see {@link TransformedBag#transformedBag(Bag, Transformer)}.
202      * </p>
203      *
204      * @param <E> The element type
205      * @param bag The bag to predicate, must not be null
206      * @param transformer The transformer for the bag, must not be null
207      * @return A transformed bag backed by the given bag
208      * @throws NullPointerException if the Bag or Transformer is null
209      */
210     public static <E> Bag<E> transformingBag(final Bag<E> bag, final Transformer<? super E, ? extends E> transformer) {
211         return TransformedBag.transformingBag(bag, transformer);
212     }
213 
214     /**
215      * Returns a transformed sorted bag backed by the given bag.
216      * <p>
217      * Each object is passed through the transformer as it is added to the Bag.
218      * It is important not to use the original bag after invoking this method,
219      * as it is a backdoor for adding untransformed objects.
220      * </p>
221      * <p>
222      * Existing entries in the specified bag will not be transformed.
223      * If you want that behavior, see
224      * {@link TransformedSortedBag#transformedSortedBag(SortedBag, Transformer)}.
225      * </p>
226      *
227      * @param <E> The element type
228      * @param bag The bag to predicate, must not be null
229      * @param transformer The transformer for the bag, must not be null
230      * @return A transformed bag backed by the given bag
231      * @throws NullPointerException if the Bag or Transformer is null
232      */
233     public static <E> SortedBag<E> transformingSortedBag(final SortedBag<E> bag,
234                                                          final Transformer<? super E, ? extends E> transformer) {
235         return TransformedSortedBag.transformingSortedBag(bag, transformer);
236     }
237 
238     /**
239      * Returns an unmodifiable view of the given bag. Any modification attempts
240      * to the returned bag will raise an {@link UnsupportedOperationException}.
241      *
242      * @param <E> The element type
243      * @param bag The bag whose unmodifiable view is to be returned, must not be null
244      * @return An unmodifiable view of that bag
245      * @throws NullPointerException if the Bag is null
246      */
247     public static <E> Bag<E> unmodifiableBag(final Bag<? extends E> bag) {
248         return UnmodifiableBag.unmodifiableBag(bag);
249     }
250 
251     /**
252      * Returns an unmodifiable view of the given sorted bag. Any modification
253      * attempts to the returned bag will raise an
254      * {@link UnsupportedOperationException}.
255      *
256      * @param <E> The element type
257      * @param bag The bag whose unmodifiable view is to be returned, must not be null
258      * @return An unmodifiable view of that bag
259      * @throws NullPointerException if the SortedBag is null
260      */
261     public static <E> SortedBag<E> unmodifiableSortedBag(final SortedBag<E> bag) {
262         return UnmodifiableSortedBag.unmodifiableSortedBag(bag);
263     }
264 
265     /**
266      * Don't allow instances.
267      */
268     private BagUtils() {
269         // empty
270     }
271 
272 }