001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4; 018 019import org.apache.commons.collections4.bag.CollectionBag; 020import org.apache.commons.collections4.bag.HashBag; 021import org.apache.commons.collections4.bag.PredicatedBag; 022import org.apache.commons.collections4.bag.PredicatedSortedBag; 023import org.apache.commons.collections4.bag.SynchronizedBag; 024import org.apache.commons.collections4.bag.SynchronizedSortedBag; 025import org.apache.commons.collections4.bag.TransformedBag; 026import org.apache.commons.collections4.bag.TransformedSortedBag; 027import org.apache.commons.collections4.bag.TreeBag; 028import org.apache.commons.collections4.bag.UnmodifiableBag; 029import org.apache.commons.collections4.bag.UnmodifiableSortedBag; 030 031/** 032 * Provides utility methods and decorators for {@link Bag} and {@link SortedBag} instances. 033 * 034 * @since 2.1 035 * @deprecated Since 4.6.0, use {@link MultiSetUtils} instead. 036 */ 037@Deprecated 038public class BagUtils { 039 040 /** 041 * An empty unmodifiable bag. 042 */ 043 @SuppressWarnings("rawtypes") // OK, empty bag is compatible with any type 044 public static final Bag EMPTY_BAG = UnmodifiableBag.unmodifiableBag(new HashBag<>()); 045 046 /** 047 * An empty unmodifiable sorted bag. 048 */ 049 @SuppressWarnings("rawtypes") // OK, empty bag is compatible with any type 050 public static final Bag EMPTY_SORTED_BAG = 051 UnmodifiableSortedBag.unmodifiableSortedBag(new TreeBag<>()); 052 053 /** 054 * Returns a bag that complies to the Collection contract, backed by the given bag. 055 * 056 * @param <E> The element type 057 * @param bag The bag to decorate, must not be null 058 * @return A Bag that complies to the Collection contract 059 * @throws NullPointerException if bag is null 060 * @since 4.0 061 */ 062 public static <E> Bag<E> collectionBag(final Bag<E> bag) { 063 return CollectionBag.collectionBag(bag); 064 } 065 066 /** 067 * Gets an empty {@code Bag}. 068 * 069 * @param <E> The element type 070 * @return An empty Bag 071 */ 072 @SuppressWarnings("unchecked") // OK, empty bag is compatible with any type 073 public static <E> Bag<E> emptyBag() { 074 return EMPTY_BAG; 075 } 076 077 /** 078 * Gets an empty {@code SortedBag}. 079 * 080 * @param <E> The element type 081 * @return An empty sorted Bag 082 */ 083 @SuppressWarnings("unchecked") // OK, empty bag is compatible with any type 084 public static <E> SortedBag<E> emptySortedBag() { 085 return (SortedBag<E>) EMPTY_SORTED_BAG; 086 } 087 088 /** 089 * Returns a predicated (validating) bag backed by the given bag. 090 * <p> 091 * Only objects that pass the test in the given predicate can be added to 092 * the bag. Trying to add an invalid object results in an 093 * IllegalArgumentException. It is important not to use the original bag 094 * after invoking this method, as it is a backdoor for adding invalid 095 * objects. 096 * </p> 097 * 098 * @param <E> The element type 099 * @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}