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 * http://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 java.lang.reflect.Array; 020import java.util.ArrayList; 021import java.util.Collection; 022import java.util.Comparator; 023import java.util.Enumeration; 024import java.util.HashMap; 025import java.util.HashSet; 026import java.util.Iterator; 027import java.util.LinkedList; 028import java.util.List; 029import java.util.ListIterator; 030import java.util.Map; 031import java.util.Set; 032 033import org.apache.commons.collections4.bag.HashBag; 034import org.apache.commons.collections4.collection.PredicatedCollection; 035import org.apache.commons.collections4.collection.SynchronizedCollection; 036import org.apache.commons.collections4.collection.TransformedCollection; 037import org.apache.commons.collections4.collection.UnmodifiableBoundedCollection; 038import org.apache.commons.collections4.collection.UnmodifiableCollection; 039import org.apache.commons.collections4.functors.TruePredicate; 040import org.apache.commons.collections4.iterators.CollatingIterator; 041import org.apache.commons.collections4.iterators.PermutationIterator; 042 043/** 044 * Provides utility methods and decorators for {@link Collection} instances. 045 * <p> 046 * NOTE: From 4.0, method parameters will take {@link Iterable} objects when possible. 047 * 048 * @since 1.0 049 * @version $Id: CollectionUtils.html 972421 2015-11-14 20:00:04Z tn $ 050 */ 051public class CollectionUtils { 052 053 /** 054 * Helper class to easily access cardinality properties of two collections. 055 * @param <O> the element type 056 */ 057 private static class CardinalityHelper<O> { 058 059 /** Contains the cardinality for each object in collection A. */ 060 final Map<O, Integer> cardinalityA; 061 062 /** Contains the cardinality for each object in collection B. */ 063 final Map<O, Integer> cardinalityB; 064 065 /** 066 * Create a new CardinalityHelper for two collections. 067 * @param a the first collection 068 * @param b the second collection 069 */ 070 public CardinalityHelper(final Iterable<? extends O> a, final Iterable<? extends O> b) { 071 cardinalityA = CollectionUtils.<O>getCardinalityMap(a); 072 cardinalityB = CollectionUtils.<O>getCardinalityMap(b); 073 } 074 075 /** 076 * Returns the maximum frequency of an object. 077 * @param obj the object 078 * @return the maximum frequency of the object 079 */ 080 public final int max(final Object obj) { 081 return Math.max(freqA(obj), freqB(obj)); 082 } 083 084 /** 085 * Returns the minimum frequency of an object. 086 * @param obj the object 087 * @return the minimum frequency of the object 088 */ 089 public final int min(final Object obj) { 090 return Math.min(freqA(obj), freqB(obj)); 091 } 092 093 /** 094 * Returns the frequency of this object in collection A. 095 * @param obj the object 096 * @return the frequency of the object in collection A 097 */ 098 public int freqA(final Object obj) { 099 return getFreq(obj, cardinalityA); 100 } 101 102 /** 103 * Returns the frequency of this object in collection B. 104 * @param obj the object 105 * @return the frequency of the object in collection B 106 */ 107 public int freqB(final Object obj) { 108 return getFreq(obj, cardinalityB); 109 } 110 111 private final int getFreq(final Object obj, final Map<?, Integer> freqMap) { 112 final Integer count = freqMap.get(obj); 113 if (count != null) { 114 return count.intValue(); 115 } 116 return 0; 117 } 118 } 119 120 /** 121 * Helper class for set-related operations, e.g. union, subtract, intersection. 122 * @param <O> the element type 123 */ 124 private static class SetOperationCardinalityHelper<O> extends CardinalityHelper<O> implements Iterable<O> { 125 126 /** Contains the unique elements of the two collections. */ 127 private final Set<O> elements; 128 129 /** Output collection. */ 130 private final List<O> newList; 131 132 /** 133 * Create a new set operation helper from the two collections. 134 * @param a the first collection 135 * @param b the second collection 136 */ 137 public SetOperationCardinalityHelper(final Iterable<? extends O> a, final Iterable<? extends O> b) { 138 super(a, b); 139 elements = new HashSet<O>(); 140 addAll(elements, a); 141 addAll(elements, b); 142 // the resulting list must contain at least each unique element, but may grow 143 newList = new ArrayList<O>(elements.size()); 144 } 145 146 public Iterator<O> iterator() { 147 return elements.iterator(); 148 } 149 150 /** 151 * Add the object {@code count} times to the result collection. 152 * @param obj the object to add 153 * @param count the count 154 */ 155 public void setCardinality(final O obj, final int count) { 156 for (int i = 0; i < count; i++) { 157 newList.add(obj); 158 } 159 } 160 161 /** 162 * Returns the resulting collection. 163 * @return the result 164 */ 165 public Collection<O> list() { 166 return newList; 167 } 168 169 } 170 171 /** 172 * An empty unmodifiable collection. 173 * The JDK provides empty Set and List implementations which could be used for 174 * this purpose. However they could be cast to Set or List which might be 175 * undesirable. This implementation only implements Collection. 176 */ 177 @SuppressWarnings("rawtypes") // we deliberately use the raw type here 178 public static final Collection EMPTY_COLLECTION = 179 UnmodifiableCollection.unmodifiableCollection(new ArrayList<Object>()); 180 181 /** 182 * <code>CollectionUtils</code> should not normally be instantiated. 183 */ 184 private CollectionUtils() {} 185 186 /** 187 * Returns the immutable EMPTY_COLLECTION with generic type safety. 188 * 189 * @see #EMPTY_COLLECTION 190 * @since 4.0 191 * @param <T> the element type 192 * @return immutable empty collection 193 */ 194 @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type 195 public static <T> Collection<T> emptyCollection() { 196 return EMPTY_COLLECTION; 197 } 198 199 /** 200 * Returns an immutable empty collection if the argument is <code>null</code>, 201 * or the argument itself otherwise. 202 * 203 * @param <T> the element type 204 * @param collection the collection, possibly <code>null</code> 205 * @return an empty collection if the argument is <code>null</code> 206 */ 207 @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type 208 public static <T> Collection<T> emptyIfNull(final Collection<T> collection) { 209 return collection == null ? EMPTY_COLLECTION : collection; 210 } 211 212 /** 213 * Returns a {@link Collection} containing the union of the given 214 * {@link Iterable}s. 215 * <p> 216 * The cardinality of each element in the returned {@link Collection} will 217 * be equal to the maximum of the cardinality of that element in the two 218 * given {@link Iterable}s. 219 * 220 * @param a the first collection, must not be null 221 * @param b the second collection, must not be null 222 * @param <O> the generic type that is able to represent the types contained 223 * in both input collections. 224 * @return the union of the two collections 225 * @see Collection#addAll 226 */ 227 public static <O> Collection<O> union(final Iterable<? extends O> a, final Iterable<? extends O> b) { 228 final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<O>(a, b); 229 for (final O obj : helper) { 230 helper.setCardinality(obj, helper.max(obj)); 231 } 232 return helper.list(); 233 } 234 235 /** 236 * Returns a {@link Collection} containing the intersection of the given 237 * {@link Iterable}s. 238 * <p> 239 * The cardinality of each element in the returned {@link Collection} will 240 * be equal to the minimum of the cardinality of that element in the two 241 * given {@link Iterable}s. 242 * 243 * @param a the first collection, must not be null 244 * @param b the second collection, must not be null 245 * @param <O> the generic type that is able to represent the types contained 246 * in both input collections. 247 * @return the intersection of the two collections 248 * @see Collection#retainAll 249 * @see #containsAny 250 */ 251 public static <O> Collection<O> intersection(final Iterable<? extends O> a, final Iterable<? extends O> b) { 252 final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<O>(a, b); 253 for (final O obj : helper) { 254 helper.setCardinality(obj, helper.min(obj)); 255 } 256 return helper.list(); 257 } 258 259 /** 260 * Returns a {@link Collection} containing the exclusive disjunction 261 * (symmetric difference) of the given {@link Iterable}s. 262 * <p> 263 * The cardinality of each element <i>e</i> in the returned 264 * {@link Collection} will be equal to 265 * <tt>max(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>)) - min(cardinality(<i>e</i>,<i>a</i>), 266 * cardinality(<i>e</i>,<i>b</i>))</tt>. 267 * <p> 268 * This is equivalent to 269 * <tt>{@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)})</tt> 270 * or 271 * <tt>{@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)})</tt>. 272 273 * @param a the first collection, must not be null 274 * @param b the second collection, must not be null 275 * @param <O> the generic type that is able to represent the types contained 276 * in both input collections. 277 * @return the symmetric difference of the two collections 278 */ 279 public static <O> Collection<O> disjunction(final Iterable<? extends O> a, final Iterable<? extends O> b) { 280 final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<O>(a, b); 281 for (final O obj : helper) { 282 helper.setCardinality(obj, helper.max(obj) - helper.min(obj)); 283 } 284 return helper.list(); 285 } 286 287 /** 288 * Returns a new {@link Collection} containing <tt><i>a</i> - <i>b</i></tt>. 289 * The cardinality of each element <i>e</i> in the returned {@link Collection} 290 * will be the cardinality of <i>e</i> in <i>a</i> minus the cardinality 291 * of <i>e</i> in <i>b</i>, or zero, whichever is greater. 292 * 293 * @param a the collection to subtract from, must not be null 294 * @param b the collection to subtract, must not be null 295 * @param <O> the generic type that is able to represent the types contained 296 * in both input collections. 297 * @return a new collection with the results 298 * @see Collection#removeAll 299 */ 300 public static <O> Collection<O> subtract(final Iterable<? extends O> a, final Iterable<? extends O> b) { 301 final Predicate<O> p = TruePredicate.truePredicate(); 302 return subtract(a, b, p); 303 } 304 305 /** 306 * Returns a new {@link Collection} containing <i>a</i> minus a subset of 307 * <i>b</i>. Only the elements of <i>b</i> that satisfy the predicate 308 * condition, <i>p</i> are subtracted from <i>a</i>. 309 * 310 * <p>The cardinality of each element <i>e</i> in the returned {@link Collection} 311 * that satisfies the predicate condition will be the cardinality of <i>e</i> in <i>a</i> 312 * minus the cardinality of <i>e</i> in <i>b</i>, or zero, whichever is greater.</p> 313 * <p>The cardinality of each element <i>e</i> in the returned {@link Collection} that does <b>not</b> 314 * satisfy the predicate condition will be equal to the cardinality of <i>e</i> in <i>a</i>.</p> 315 * 316 * @param a the collection to subtract from, must not be null 317 * @param b the collection to subtract, must not be null 318 * @param p the condition used to determine which elements of <i>b</i> are 319 * subtracted. 320 * @param <O> the generic type that is able to represent the types contained 321 * in both input collections. 322 * @return a new collection with the results 323 * @since 4.0 324 * @see Collection#removeAll 325 */ 326 public static <O> Collection<O> subtract(final Iterable<? extends O> a, 327 final Iterable<? extends O> b, 328 final Predicate<O> p) { 329 final ArrayList<O> list = new ArrayList<O>(); 330 final HashBag<O> bag = new HashBag<O>(); 331 for (final O element : b) { 332 if (p.evaluate(element)) { 333 bag.add(element); 334 } 335 } 336 for (final O element : a) { 337 if (!bag.remove(element, 1)) { 338 list.add(element); 339 } 340 } 341 return list; 342 } 343 344 /** 345 * Returns <code>true</code> iff all elements of {@code coll2} are also contained 346 * in {@code coll1}. The cardinality of values in {@code coll2} is not taken into account, 347 * which is the same behavior as {@link Collection#containsAll(Collection)}. 348 * <p> 349 * In other words, this method returns <code>true</code> iff the 350 * {@link #intersection} of <i>coll1</i> and <i>coll2</i> has the same cardinality as 351 * the set of unique values from {@code coll2}. In case {@code coll2} is empty, {@code true} 352 * will be returned. 353 * <p> 354 * This method is intended as a replacement for {@link Collection#containsAll(Collection)} 355 * with a guaranteed runtime complexity of {@code O(n + m)}. Depending on the type of 356 * {@link Collection} provided, this method will be much faster than calling 357 * {@link Collection#containsAll(Collection)} instead, though this will come at the 358 * cost of an additional space complexity O(n). 359 * 360 * @param coll1 the first collection, must not be null 361 * @param coll2 the second collection, must not be null 362 * @return <code>true</code> iff the intersection of the collections has the same cardinality 363 * as the set of unique elements from the second collection 364 * @since 4.0 365 */ 366 public static boolean containsAll(final Collection<?> coll1, final Collection<?> coll2) { 367 if (coll2.isEmpty()) { 368 return true; 369 } else { 370 final Iterator<?> it = coll1.iterator(); 371 final Set<Object> elementsAlreadySeen = new HashSet<Object>(); 372 for (final Object nextElement : coll2) { 373 if (elementsAlreadySeen.contains(nextElement)) { 374 continue; 375 } 376 377 boolean foundCurrentElement = false; 378 while (it.hasNext()) { 379 final Object p = it.next(); 380 elementsAlreadySeen.add(p); 381 if (nextElement == null ? p == null : nextElement.equals(p)) { 382 foundCurrentElement = true; 383 break; 384 } 385 } 386 387 if (foundCurrentElement) { 388 continue; 389 } else { 390 return false; 391 } 392 } 393 return true; 394 } 395 } 396 397 /** 398 * Returns <code>true</code> iff at least one element is in both collections. 399 * <p> 400 * In other words, this method returns <code>true</code> iff the 401 * {@link #intersection} of <i>coll1</i> and <i>coll2</i> is not empty. 402 * 403 * @param coll1 the first collection, must not be null 404 * @param coll2 the second collection, must not be null 405 * @return <code>true</code> iff the intersection of the collections is non-empty 406 * @since 2.1 407 * @see #intersection 408 */ 409 public static boolean containsAny(final Collection<?> coll1, final Collection<?> coll2) { 410 if (coll1.size() < coll2.size()) { 411 for (final Object aColl1 : coll1) { 412 if (coll2.contains(aColl1)) { 413 return true; 414 } 415 } 416 } else { 417 for (final Object aColl2 : coll2) { 418 if (coll1.contains(aColl2)) { 419 return true; 420 } 421 } 422 } 423 return false; 424 } 425 426 /** 427 * Returns a {@link Map} mapping each unique element in the given 428 * {@link Collection} to an {@link Integer} representing the number 429 * of occurrences of that element in the {@link Collection}. 430 * <p> 431 * Only those elements present in the collection will appear as 432 * keys in the map. 433 * 434 * @param <O> the type of object in the returned {@link Map}. This is a super type of <I>. 435 * @param coll the collection to get the cardinality map for, must not be null 436 * @return the populated cardinality map 437 */ 438 public static <O> Map<O, Integer> getCardinalityMap(final Iterable<? extends O> coll) { 439 final Map<O, Integer> count = new HashMap<O, Integer>(); 440 for (final O obj : coll) { 441 final Integer c = count.get(obj); 442 if (c == null) { 443 count.put(obj, Integer.valueOf(1)); 444 } else { 445 count.put(obj, Integer.valueOf(c.intValue() + 1)); 446 } 447 } 448 return count; 449 } 450 451 /** 452 * Returns <tt>true</tt> iff <i>a</i> is a sub-collection of <i>b</i>, 453 * that is, iff the cardinality of <i>e</i> in <i>a</i> is less than or 454 * equal to the cardinality of <i>e</i> in <i>b</i>, for each element <i>e</i> 455 * in <i>a</i>. 456 * 457 * @param a the first (sub?) collection, must not be null 458 * @param b the second (super?) collection, must not be null 459 * @return <code>true</code> iff <i>a</i> is a sub-collection of <i>b</i> 460 * @see #isProperSubCollection 461 * @see Collection#containsAll 462 */ 463 public static boolean isSubCollection(final Collection<?> a, final Collection<?> b) { 464 final CardinalityHelper<Object> helper = new CardinalityHelper<Object>(a, b); 465 for (final Object obj : a) { 466 if (helper.freqA(obj) > helper.freqB(obj)) { 467 return false; 468 } 469 } 470 return true; 471 } 472 473 /** 474 * Returns <tt>true</tt> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>, 475 * that is, iff the cardinality of <i>e</i> in <i>a</i> is less 476 * than or equal to the cardinality of <i>e</i> in <i>b</i>, 477 * for each element <i>e</i> in <i>a</i>, and there is at least one 478 * element <i>f</i> such that the cardinality of <i>f</i> in <i>b</i> 479 * is strictly greater than the cardinality of <i>f</i> in <i>a</i>. 480 * <p> 481 * The implementation assumes 482 * <ul> 483 * <li><code>a.size()</code> and <code>b.size()</code> represent the 484 * total cardinality of <i>a</i> and <i>b</i>, resp. </li> 485 * <li><code>a.size() < Integer.MAXVALUE</code></li> 486 * </ul> 487 * 488 * @param a the first (sub?) collection, must not be null 489 * @param b the second (super?) collection, must not be null 490 * @return <code>true</code> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i> 491 * @see #isSubCollection 492 * @see Collection#containsAll 493 */ 494 public static boolean isProperSubCollection(final Collection<?> a, final Collection<?> b) { 495 return a.size() < b.size() && CollectionUtils.isSubCollection(a, b); 496 } 497 498 /** 499 * Returns <tt>true</tt> iff the given {@link Collection}s contain 500 * exactly the same elements with exactly the same cardinalities. 501 * <p> 502 * That is, iff the cardinality of <i>e</i> in <i>a</i> is 503 * equal to the cardinality of <i>e</i> in <i>b</i>, 504 * for each element <i>e</i> in <i>a</i> or <i>b</i>. 505 * 506 * @param a the first collection, must not be null 507 * @param b the second collection, must not be null 508 * @return <code>true</code> iff the collections contain the same elements with the same cardinalities. 509 */ 510 public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b) { 511 if(a.size() != b.size()) { 512 return false; 513 } 514 final CardinalityHelper<Object> helper = new CardinalityHelper<Object>(a, b); 515 if(helper.cardinalityA.size() != helper.cardinalityB.size()) { 516 return false; 517 } 518 for( final Object obj : helper.cardinalityA.keySet()) { 519 if(helper.freqA(obj) != helper.freqB(obj)) { 520 return false; 521 } 522 } 523 return true; 524 } 525 526 /** 527 * Returns <tt>true</tt> iff the given {@link Collection}s contain 528 * exactly the same elements with exactly the same cardinalities. 529 * <p> 530 * That is, iff the cardinality of <i>e</i> in <i>a</i> is 531 * equal to the cardinality of <i>e</i> in <i>b</i>, 532 * for each element <i>e</i> in <i>a</i> or <i>b</i>. 533 * 534 * @param a the first collection, must not be null 535 * @param b the second collection, must not be null 536 * @param equator the Equator used for testing equality 537 * @return <code>true</code> iff the collections contain the same elements with the same cardinalities. 538 * @throws IllegalArgumentException if the equator is null 539 * @since 4.0 540 */ 541 @SuppressWarnings({ "unchecked", "rawtypes" }) // we don't know the types due to wildcards in the signature 542 public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b, final Equator<?> equator) { 543 if (equator == null) { 544 throw new IllegalArgumentException("equator may not be null"); 545 } 546 547 if(a.size() != b.size()) { 548 return false; 549 } 550 551 final Transformer transformer = new Transformer() { 552 public EquatorWrapper<?> transform(final Object input) { 553 return new EquatorWrapper(equator, input); 554 } 555 }; 556 557 return isEqualCollection(collect(a, transformer), collect(b, transformer)); 558 } 559 560 /** 561 * Wraps another object and uses the provided Equator to implement 562 * {@link #equals(Object)} and {@link #hashCode()}. 563 * <p> 564 * This class can be used to store objects into a Map. 565 * 566 * @param <O> the element type 567 * @since 4.0 568 */ 569 private static class EquatorWrapper<O> { 570 private final Equator<O> equator; 571 private final O object; 572 573 public EquatorWrapper(final Equator<O> equator, final O object) { 574 this.equator = equator; 575 this.object = object; 576 } 577 578 public O getObject() { 579 return object; 580 } 581 582 @Override 583 public boolean equals(final Object obj) { 584 if (!(obj instanceof EquatorWrapper)) { 585 return false; 586 } 587 @SuppressWarnings("unchecked") 588 final EquatorWrapper<O> otherObj = (EquatorWrapper<O>) obj; 589 return equator.equate(object, otherObj.getObject()); 590 } 591 592 @Override 593 public int hashCode() { 594 return equator.hash(object); 595 } 596 } 597 598 /** 599 * Returns the number of occurrences of <i>obj</i> in <i>coll</i>. 600 * 601 * @param obj the object to find the cardinality of 602 * @param coll the {@link Iterable} to search 603 * @param <O> the type of object that the {@link Iterable} may contain. 604 * @return the the number of occurrences of obj in coll 605 */ 606 public static <O> int cardinality(final O obj, final Iterable<? super O> coll) { 607 if (coll instanceof Set<?>) { 608 return ((Set<? super O>) coll).contains(obj) ? 1 : 0; 609 } 610 if (coll instanceof Bag<?>) { 611 return ((Bag<? super O>) coll).getCount(obj); 612 } 613 int count = 0; 614 if (obj == null) { 615 for (final Object element : coll) { 616 if (element == null) { 617 count++; 618 } 619 } 620 } else { 621 for (final Object element : coll) { 622 if (obj.equals(element)) { 623 count++; 624 } 625 } 626 } 627 return count; 628 } 629 630 /** 631 * Finds the first element in the given collection which matches the given predicate. 632 * <p> 633 * If the input collection or predicate is null, or no element of the collection 634 * matches the predicate, null is returned. 635 * 636 * @param <T> the type of object the {@link Iterable} contains 637 * @param collection the collection to search, may be null 638 * @param predicate the predicate to use, may be null 639 * @return the first element of the collection which matches the predicate or null if none could be found 640 */ 641 public static <T> T find(final Iterable<T> collection, final Predicate<? super T> predicate) { 642 if (collection != null && predicate != null) { 643 for (final T item : collection) { 644 if (predicate.evaluate(item)) { 645 return item; 646 } 647 } 648 } 649 return null; 650 } 651 652 /** 653 * Executes the given closure on each element in the collection. 654 * <p> 655 * If the input collection or closure is null, there is no change made. 656 * 657 * @param <T> the type of object the {@link Iterable} contains 658 * @param <C> the closure type 659 * @param collection the collection to get the input from, may be null 660 * @param closure the closure to perform, may be null 661 * @return closure 662 */ 663 public static <T, C extends Closure<? super T>> C forAllDo(final Iterable<T> collection, final C closure) { 664 if (collection != null && closure != null) { 665 for (final T element : collection) { 666 closure.execute(element); 667 } 668 } 669 return closure; 670 } 671 672 /** 673 * Executes the given closure on each element in the collection. 674 * <p> 675 * If the input collection or closure is null, there is no change made. 676 * 677 * @param <T> the type of object the {@link Iterator} contains 678 * @param <C> the closure type 679 * @param iterator the iterator to get the input from, may be null 680 * @param closure the closure to perform, may be null 681 * @return closure 682 * @since 4.0 683 */ 684 public static <T, C extends Closure<? super T>> C forAllDo(final Iterator<T> iterator, final C closure) { 685 if (iterator != null && closure != null) { 686 while (iterator.hasNext()) { 687 closure.execute(iterator.next()); 688 } 689 } 690 return closure; 691 } 692 693 /** 694 * Executes the given closure on each but the last element in the collection. 695 * <p> 696 * If the input collection or closure is null, there is no change made. 697 * 698 * @param <T> the type of object the {@link Iterable} contains 699 * @param <C> the closure type 700 * @param collection the collection to get the input from, may be null 701 * @param closure the closure to perform, may be null 702 * @return the last element in the collection, or null if either collection or closure is null 703 * @since 4.0 704 */ 705 public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterable<T> collection, 706 final C closure) { 707 return collection != null && closure != null ? forAllButLastDo(collection.iterator(), closure) : null; 708 } 709 710 /** 711 * Executes the given closure on each but the last element in the collection. 712 * <p> 713 * If the input collection or closure is null, there is no change made. 714 * 715 * @param <T> the type of object the {@link Collection} contains 716 * @param <C> the closure type 717 * @param iterator the iterator to get the input from, may be null 718 * @param closure the closure to perform, may be null 719 * @return the last element in the collection, or null if either iterator or closure is null 720 * @since 4.0 721 */ 722 public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterator<T> iterator, final C closure) { 723 if (iterator != null && closure != null) { 724 while (iterator.hasNext()) { 725 final T element = iterator.next(); 726 if (iterator.hasNext()) { 727 closure.execute(element); 728 } else { 729 return element; 730 } 731 } 732 } 733 return null; 734 } 735 736 /** 737 * Filter the collection by applying a Predicate to each element. If the 738 * predicate returns false, remove the element. 739 * <p> 740 * If the input collection or predicate is null, there is no change made. 741 * 742 * @param <T> the type of object the {@link Iterable} contains 743 * @param collection the collection to get the input from, may be null 744 * @param predicate the predicate to use as a filter, may be null 745 * @return true if the collection is modified by this call, false otherwise. 746 */ 747 public static <T> boolean filter(final Iterable<T> collection, final Predicate<? super T> predicate) { 748 boolean result = false; 749 if (collection != null && predicate != null) { 750 for (final Iterator<T> it = collection.iterator(); it.hasNext();) { 751 if (!predicate.evaluate(it.next())) { 752 it.remove(); 753 result = true; 754 } 755 } 756 } 757 return result; 758 } 759 760 /** 761 * Filter the collection by applying a Predicate to each element. If the 762 * predicate returns true, remove the element. 763 * <p> 764 * This is equivalent to <pre>filter(collection, PredicateUtils.notPredicate(predicate))</pre> 765 * if predicate is != null. 766 * <p> 767 * If the input collection or predicate is null, there is no change made. 768 * 769 * @param <T> the type of object the {@link Iterable} contains 770 * @param collection the collection to get the input from, may be null 771 * @param predicate the predicate to use as a filter, may be null 772 * @return true if the collection is modified by this call, false otherwise. 773 */ 774 public static <T> boolean filterInverse(final Iterable<T> collection, final Predicate<? super T> predicate) { 775 return filter(collection, predicate == null ? null : PredicateUtils.notPredicate(predicate)); 776 } 777 778 /** 779 * Transform the collection by applying a Transformer to each element. 780 * <p> 781 * If the input collection or transformer is null, there is no change made. 782 * <p> 783 * This routine is best for Lists, for which set() is used to do the 784 * transformations "in place." For other Collections, clear() and addAll() 785 * are used to replace elements. 786 * <p> 787 * If the input collection controls its input, such as a Set, and the 788 * Transformer creates duplicates (or are otherwise invalid), the collection 789 * may reduce in size due to calling this method. 790 * 791 * @param <C> the type of object the {@link Collection} contains 792 * @param collection the {@link Collection} to get the input from, may be null 793 * @param transformer the transformer to perform, may be null 794 */ 795 public static <C> void transform(final Collection<C> collection, 796 final Transformer<? super C, ? extends C> transformer) { 797 798 if (collection != null && transformer != null) { 799 if (collection instanceof List<?>) { 800 final List<C> list = (List<C>) collection; 801 for (final ListIterator<C> it = list.listIterator(); it.hasNext();) { 802 it.set(transformer.transform(it.next())); 803 } 804 } else { 805 final Collection<C> resultCollection = collect(collection, transformer); 806 collection.clear(); 807 collection.addAll(resultCollection); 808 } 809 } 810 } 811 812 /** 813 * Counts the number of elements in the input collection that match the 814 * predicate. 815 * <p> 816 * A <code>null</code> collection or predicate matches no elements. 817 * 818 * @param <C> the type of object the {@link Iterable} contains 819 * @param input the {@link Iterable} to get the input from, may be null 820 * @param predicate the predicate to use, may be null 821 * @return the number of matches for the predicate in the collection 822 */ 823 public static <C> int countMatches(final Iterable<C> input, final Predicate<? super C> predicate) { 824 int count = 0; 825 if (input != null && predicate != null) { 826 for (final C o : input) { 827 if (predicate.evaluate(o)) { 828 count++; 829 } 830 } 831 } 832 return count; 833 } 834 835 /** 836 * Answers true if a predicate is true for at least one element of a 837 * collection. 838 * <p> 839 * A <code>null</code> collection or predicate returns false. 840 * 841 * @param <C> the type of object the {@link Iterable} contains 842 * @param input the {@link Iterable} to get the input from, may be null 843 * @param predicate the predicate to use, may be null 844 * @return true if at least one element of the collection matches the predicate 845 */ 846 public static <C> boolean exists(final Iterable<C> input, final Predicate<? super C> predicate) { 847 if (input != null && predicate != null) { 848 for (final C o : input) { 849 if (predicate.evaluate(o)) { 850 return true; 851 } 852 } 853 } 854 return false; 855 } 856 857 /** 858 * Answers true if a predicate is true for every element of a 859 * collection. 860 * <p> 861 * A <code>null</code> predicate returns false.<br/> 862 * A <code>null</code> or empty collection returns true. 863 * 864 * @param <C> the type of object the {@link Iterable} contains 865 * @param input the {@link Iterable} to get the input from, may be null 866 * @param predicate the predicate to use, may be null 867 * @return true if every element of the collection matches the predicate or if the 868 * collection is empty, false otherwise 869 * @since 4.0 870 */ 871 public static <C> boolean matchesAll(final Iterable<C> input, final Predicate<? super C> predicate) { 872 if (predicate == null) { 873 return false; 874 } 875 876 if (input != null) { 877 for (final C o : input) { 878 if (!predicate.evaluate(o)) { 879 return false; 880 } 881 } 882 } 883 return true; 884 } 885 886 /** 887 * Selects all elements from input collection which match the given 888 * predicate into an output collection. 889 * <p> 890 * A <code>null</code> predicate matches no elements. 891 * 892 * @param <O> the type of object the {@link Iterable} contains 893 * @param inputCollection the collection to get the input from, may not be null 894 * @param predicate the predicate to use, may be null 895 * @return the elements matching the predicate (new list) 896 * @throws NullPointerException if the input collection is null 897 */ 898 public static <O> Collection<O> select(final Iterable<? extends O> inputCollection, 899 final Predicate<? super O> predicate) { 900 final Collection<O> answer = inputCollection instanceof Collection<?> ? 901 new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>(); 902 return select(inputCollection, predicate, answer); 903 } 904 905 /** 906 * Selects all elements from input collection which match the given 907 * predicate and adds them to outputCollection. 908 * <p> 909 * If the input collection or predicate is null, there is no change to the 910 * output collection. 911 * 912 * @param <O> the type of object the {@link Iterable} contains 913 * @param <R> the type of the output {@link Collection} 914 * @param inputCollection the collection to get the input from, may be null 915 * @param predicate the predicate to use, may be null 916 * @param outputCollection the collection to output into, may not be null if the inputCollection 917 * and predicate or not null 918 * @return the outputCollection 919 */ 920 public static <O, R extends Collection<? super O>> R select(final Iterable<? extends O> inputCollection, 921 final Predicate<? super O> predicate, final R outputCollection) { 922 923 if (inputCollection != null && predicate != null) { 924 for (final O item : inputCollection) { 925 if (predicate.evaluate(item)) { 926 outputCollection.add(item); 927 } 928 } 929 } 930 return outputCollection; 931 } 932 933 /** 934 * Selects all elements from inputCollection which don't match the given 935 * predicate into an output collection. 936 * <p> 937 * If the input predicate is <code>null</code>, the result is an empty 938 * list. 939 * 940 * @param <O> the type of object the {@link Iterable} contains 941 * @param inputCollection the collection to get the input from, may not be null 942 * @param predicate the predicate to use, may be null 943 * @return the elements <b>not</b> matching the predicate (new list) 944 * @throws NullPointerException if the input collection is null 945 */ 946 public static <O> Collection<O> selectRejected(final Iterable<? extends O> inputCollection, 947 final Predicate<? super O> predicate) { 948 final Collection<O> answer = inputCollection instanceof Collection<?> ? 949 new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>(); 950 return selectRejected(inputCollection, predicate, answer); 951 } 952 953 /** 954 * Selects all elements from inputCollection which don't match the given 955 * predicate and adds them to outputCollection. 956 * <p> 957 * If the input predicate is <code>null</code>, no elements are added to 958 * <code>outputCollection</code>. 959 * 960 * @param <O> the type of object the {@link Iterable} contains 961 * @param <R> the type of the output {@link Collection} 962 * @param inputCollection the collection to get the input from, may be null 963 * @param predicate the predicate to use, may be null 964 * @param outputCollection the collection to output into, may not be null if the inputCollection 965 * and predicate or not null 966 * @return outputCollection 967 */ 968 public static <O, R extends Collection<? super O>> R selectRejected(final Iterable<? extends O> inputCollection, 969 final Predicate<? super O> predicate, final R outputCollection) { 970 971 if (inputCollection != null && predicate != null) { 972 for (final O item : inputCollection) { 973 if (!predicate.evaluate(item)) { 974 outputCollection.add(item); 975 } 976 } 977 } 978 return outputCollection; 979 } 980 981 /** 982 * Returns a new Collection consisting of the elements of inputCollection 983 * transformed by the given transformer. 984 * <p> 985 * If the input transformer is null, the result is an empty list. 986 * 987 * @param <I> the type of object in the input collection 988 * @param <O> the type of object in the output collection 989 * @param inputCollection the collection to get the input from, may not be null 990 * @param transformer the transformer to use, may be null 991 * @return the transformed result (new list) 992 * @throws NullPointerException if the input collection is null 993 */ 994 public static <I, O> Collection<O> collect(final Iterable<I> inputCollection, 995 final Transformer<? super I, ? extends O> transformer) { 996 final Collection<O> answer = inputCollection instanceof Collection<?> ? 997 new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>(); 998 return collect(inputCollection, transformer, answer); 999 } 1000 1001 /** 1002 * Transforms all elements from the inputIterator with the given transformer 1003 * and adds them to the outputCollection. 1004 * <p> 1005 * If the input iterator or transformer is null, the result is an empty 1006 * list. 1007 * 1008 * @param inputIterator the iterator to get the input from, may be null 1009 * @param transformer the transformer to use, may be null 1010 * @param <I> the type of object in the input collection 1011 * @param <O> the type of object in the output collection 1012 * @return the transformed result (new list) 1013 */ 1014 public static <I, O> Collection<O> collect(final Iterator<I> inputIterator, 1015 final Transformer<? super I, ? extends O> transformer) { 1016 return collect(inputIterator, transformer, new ArrayList<O>()); 1017 } 1018 1019 /** 1020 * Transforms all elements from inputCollection with the given transformer 1021 * and adds them to the outputCollection. 1022 * <p> 1023 * If the input collection or transformer is null, there is no change to the 1024 * output collection. 1025 * 1026 * @param <I> the type of object in the input collection 1027 * @param <O> the type of object in the output collection 1028 * @param <R> the output type of the transformer - this extends O. 1029 * @param inputCollection the collection to get the input from, may be null 1030 * @param transformer the transformer to use, may be null 1031 * @param outputCollection the collection to output into, may not be null if the inputCollection 1032 * and transformer are not null 1033 * @return the outputCollection with the transformed input added 1034 * @throws NullPointerException if the output collection is null and both, inputCollection and 1035 * transformer are not null 1036 */ 1037 public static <I, O, R extends Collection<? super O>> R collect(final Iterable<? extends I> inputCollection, 1038 final Transformer<? super I, ? extends O> transformer, final R outputCollection) { 1039 if (inputCollection != null) { 1040 return collect(inputCollection.iterator(), transformer, outputCollection); 1041 } 1042 return outputCollection; 1043 } 1044 1045 /** 1046 * Transforms all elements from the inputIterator with the given transformer 1047 * and adds them to the outputCollection. 1048 * <p> 1049 * If the input iterator or transformer is null, there is no change to the 1050 * output collection. 1051 * 1052 * @param inputIterator the iterator to get the input from, may be null 1053 * @param transformer the transformer to use, may be null 1054 * @param outputCollection the collection to output into, may not be null if the inputCollection 1055 * and transformer are not null 1056 * @param <I> the type of object in the input collection 1057 * @param <O> the type of object in the output collection 1058 * @param <R> the output type of the transformer - this extends O. 1059 * @return the outputCollection with the transformed input added 1060 * @throws NullPointerException if the output collection is null and both, inputCollection and 1061 * transformer are not null 1062 */ 1063 public static <I, O, R extends Collection<? super O>> R collect(final Iterator<? extends I> inputIterator, 1064 final Transformer<? super I, ? extends O> transformer, final R outputCollection) { 1065 if (inputIterator != null && transformer != null) { 1066 while (inputIterator.hasNext()) { 1067 final I item = inputIterator.next(); 1068 final O value = transformer.transform(item); 1069 outputCollection.add(value); 1070 } 1071 } 1072 return outputCollection; 1073 } 1074 1075 //----------------------------------------------------------------------- 1076 /** 1077 * Adds an element to the collection unless the element is null. 1078 * 1079 * @param <T> the type of object the {@link Collection} contains 1080 * @param collection the collection to add to, must not be null 1081 * @param object the object to add, if null it will not be added 1082 * @return true if the collection changed 1083 * @throws NullPointerException if the collection is null 1084 * @since 3.2 1085 */ 1086 public static <T> boolean addIgnoreNull(final Collection<T> collection, final T object) { 1087 if (collection == null) { 1088 throw new NullPointerException("The collection must not be null"); 1089 } 1090 return object != null && collection.add(object); 1091 } 1092 1093 /** 1094 * Adds all elements in the {@link Iterable} to the given collection. If the 1095 * {@link Iterable} is a {@link Collection} then it is cast and will be 1096 * added using {@link Collection#addAll(Collection)} instead of iterating. 1097 * 1098 * @param <C> the type of object the {@link Collection} contains 1099 * @param collection the collection to add to, must not be null 1100 * @param iterable the iterable of elements to add, must not be null 1101 * @return a boolean indicating whether the collection has changed or not. 1102 * @throws NullPointerException if the collection or iterator is null 1103 */ 1104 public static <C> boolean addAll(final Collection<C> collection, final Iterable<? extends C> iterable) { 1105 if (iterable instanceof Collection<?>) { 1106 return collection.addAll((Collection<? extends C>) iterable); 1107 } 1108 return addAll(collection, iterable.iterator()); 1109 } 1110 1111 /** 1112 * Adds all elements in the iteration to the given collection. 1113 * 1114 * @param <C> the type of object the {@link Collection} contains 1115 * @param collection the collection to add to, must not be null 1116 * @param iterator the iterator of elements to add, must not be null 1117 * @return a boolean indicating whether the collection has changed or not. 1118 * @throws NullPointerException if the collection or iterator is null 1119 */ 1120 public static <C> boolean addAll(final Collection<C> collection, final Iterator<? extends C> iterator) { 1121 boolean changed = false; 1122 while (iterator.hasNext()) { 1123 changed |= collection.add(iterator.next()); 1124 } 1125 return changed; 1126 } 1127 1128 /** 1129 * Adds all elements in the enumeration to the given collection. 1130 * 1131 * @param <C> the type of object the {@link Collection} contains 1132 * @param collection the collection to add to, must not be null 1133 * @param enumeration the enumeration of elements to add, must not be null 1134 * @return {@code true} if the collections was changed, {@code false} otherwise 1135 * @throws NullPointerException if the collection or enumeration is null 1136 */ 1137 public static <C> boolean addAll(final Collection<C> collection, final Enumeration<? extends C> enumeration) { 1138 boolean changed = false; 1139 while (enumeration.hasMoreElements()) { 1140 changed |= collection.add(enumeration.nextElement()); 1141 } 1142 return changed; 1143 } 1144 1145 /** 1146 * Adds all elements in the array to the given collection. 1147 * 1148 * @param <C> the type of object the {@link Collection} contains 1149 * @param collection the collection to add to, must not be null 1150 * @param elements the array of elements to add, must not be null 1151 * @return {@code true} if the collection was changed, {@code false} otherwise 1152 * @throws NullPointerException if the collection or array is null 1153 */ 1154 public static <C> boolean addAll(final Collection<C> collection, final C[] elements) { 1155 boolean changed = false; 1156 for (final C element : elements) { 1157 changed |= collection.add(element); 1158 } 1159 return changed; 1160 } 1161 1162 /** 1163 * Returns the <code>index</code>-th value in {@link Iterator}, throwing 1164 * <code>IndexOutOfBoundsException</code> if there is no such element. 1165 * <p> 1166 * The Iterator is advanced to <code>index</code> (or to the end, if 1167 * <code>index</code> exceeds the number of entries) as a side effect of this method. 1168 * 1169 * @param iterator the iterator to get a value from 1170 * @param index the index to get 1171 * @param <T> the type of object in the {@link Iterator} 1172 * @return the object at the specified index 1173 * @throws IndexOutOfBoundsException if the index is invalid 1174 * @throws IllegalArgumentException if the object type is invalid 1175 */ 1176 public static <T> T get(final Iterator<T> iterator, final int index) { 1177 int i = index; 1178 checkIndexBounds(i); 1179 while (iterator.hasNext()) { 1180 i--; 1181 if (i == -1) { 1182 return iterator.next(); 1183 } 1184 iterator.next(); 1185 } 1186 throw new IndexOutOfBoundsException("Entry does not exist: " + i); 1187 } 1188 1189 /** 1190 * Ensures an index is not negative. 1191 * @param index the index to check. 1192 * @throws IndexOutOfBoundsException if the index is negative. 1193 */ 1194 private static void checkIndexBounds(final int index) { 1195 if (index < 0) { 1196 throw new IndexOutOfBoundsException("Index cannot be negative: " + index); 1197 } 1198 } 1199 1200 /** 1201 * Returns the <code>index</code>-th value in the <code>iterable</code>'s {@link Iterator}, throwing 1202 * <code>IndexOutOfBoundsException</code> if there is no such element. 1203 * <p> 1204 * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}. 1205 * 1206 * @param iterable the {@link Iterable} to get a value from 1207 * @param index the index to get 1208 * @param <T> the type of object in the {@link Iterable}. 1209 * @return the object at the specified index 1210 * @throws IndexOutOfBoundsException if the index is invalid 1211 */ 1212 public static <T> T get(final Iterable<T> iterable, final int index) { 1213 checkIndexBounds(index); 1214 if (iterable instanceof List<?>) { 1215 return ((List<T>) iterable).get(index); 1216 } 1217 return get(iterable.iterator(), index); 1218 } 1219 1220 /** 1221 * Returns the <code>index</code>-th value in <code>object</code>, throwing 1222 * <code>IndexOutOfBoundsException</code> if there is no such element or 1223 * <code>IllegalArgumentException</code> if <code>object</code> is not an 1224 * instance of one of the supported types. 1225 * <p> 1226 * The supported types, and associated semantics are: 1227 * <ul> 1228 * <li> Map -- the value returned is the <code>Map.Entry</code> in position 1229 * <code>index</code> in the map's <code>entrySet</code> iterator, 1230 * if there is such an entry.</li> 1231 * <li> List -- this method is equivalent to the list's get method.</li> 1232 * <li> Array -- the <code>index</code>-th array entry is returned, 1233 * if there is such an entry; otherwise an <code>IndexOutOfBoundsException</code> 1234 * is thrown.</li> 1235 * <li> Collection -- the value returned is the <code>index</code>-th object 1236 * returned by the collection's default iterator, if there is such an element.</li> 1237 * <li> Iterator or Enumeration -- the value returned is the 1238 * <code>index</code>-th object in the Iterator/Enumeration, if there 1239 * is such an element. The Iterator/Enumeration is advanced to 1240 * <code>index</code> (or to the end, if <code>index</code> exceeds the 1241 * number of entries) as a side effect of this method.</li> 1242 * </ul> 1243 * 1244 * @param object the object to get a value from 1245 * @param index the index to get 1246 * @return the object at the specified index 1247 * @throws IndexOutOfBoundsException if the index is invalid 1248 * @throws IllegalArgumentException if the object type is invalid 1249 */ 1250 public static Object get(final Object object, final int index) { 1251 int i = index; 1252 if (i < 0) { 1253 throw new IndexOutOfBoundsException("Index cannot be negative: " + i); 1254 } 1255 if (object instanceof Map<?,?>) { 1256 final Map<?, ?> map = (Map<?, ?>) object; 1257 final Iterator<?> iterator = map.entrySet().iterator(); 1258 return get(iterator, i); 1259 } else if (object instanceof Object[]) { 1260 return ((Object[]) object)[i]; 1261 } else if (object instanceof Iterator<?>) { 1262 final Iterator<?> it = (Iterator<?>) object; 1263 while (it.hasNext()) { 1264 i--; 1265 if (i == -1) { 1266 return it.next(); 1267 } 1268 it.next(); 1269 } 1270 throw new IndexOutOfBoundsException("Entry does not exist: " + i); 1271 } else if (object instanceof Collection<?>) { 1272 final Iterator<?> iterator = ((Collection<?>) object).iterator(); 1273 return get(iterator, i); 1274 } else if (object instanceof Enumeration<?>) { 1275 final Enumeration<?> it = (Enumeration<?>) object; 1276 while (it.hasMoreElements()) { 1277 i--; 1278 if (i == -1) { 1279 return it.nextElement(); 1280 } else { 1281 it.nextElement(); 1282 } 1283 } 1284 throw new IndexOutOfBoundsException("Entry does not exist: " + i); 1285 } else if (object == null) { 1286 throw new IllegalArgumentException("Unsupported object type: null"); 1287 } else { 1288 try { 1289 return Array.get(object, i); 1290 } catch (final IllegalArgumentException ex) { 1291 throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName()); 1292 } 1293 } 1294 } 1295 1296 /** 1297 * Returns the <code>index</code>-th <code>Map.Entry</code> in the <code>map</code>'s <code>entrySet</code>, 1298 * throwing <code>IndexOutOfBoundsException</code> if there is no such element. 1299 * 1300 * @param <K> the key type in the {@link Map} 1301 * @param <V> the key type in the {@link Map} 1302 * @param map the object to get a value from 1303 * @param index the index to get 1304 * @return the object at the specified index 1305 * @throws IndexOutOfBoundsException if the index is invalid 1306 */ 1307 public static <K,V> Map.Entry<K, V> get(final Map<K,V> map, final int index) { 1308 checkIndexBounds(index); 1309 return get(map.entrySet(), index); 1310 } 1311 1312 /** 1313 * Gets the size of the collection/iterator specified. 1314 * <p> 1315 * This method can handles objects as follows 1316 * <ul> 1317 * <li>Collection - the collection size 1318 * <li>Map - the map size 1319 * <li>Array - the array size 1320 * <li>Iterator - the number of elements remaining in the iterator 1321 * <li>Enumeration - the number of elements remaining in the enumeration 1322 * </ul> 1323 * 1324 * @param object the object to get the size of, may be null 1325 * @return the size of the specified collection or 0 if the object was null 1326 * @throws IllegalArgumentException thrown if object is not recognised 1327 * @since 3.1 1328 */ 1329 public static int size(final Object object) { 1330 if (object == null) { 1331 return 0; 1332 } 1333 int total = 0; 1334 if (object instanceof Map<?,?>) { 1335 total = ((Map<?, ?>) object).size(); 1336 } else if (object instanceof Collection<?>) { 1337 total = ((Collection<?>) object).size(); 1338 } else if (object instanceof Object[]) { 1339 total = ((Object[]) object).length; 1340 } else if (object instanceof Iterator<?>) { 1341 final Iterator<?> it = (Iterator<?>) object; 1342 while (it.hasNext()) { 1343 total++; 1344 it.next(); 1345 } 1346 } else if (object instanceof Enumeration<?>) { 1347 final Enumeration<?> it = (Enumeration<?>) object; 1348 while (it.hasMoreElements()) { 1349 total++; 1350 it.nextElement(); 1351 } 1352 } else { 1353 try { 1354 total = Array.getLength(object); 1355 } catch (final IllegalArgumentException ex) { 1356 throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName()); 1357 } 1358 } 1359 return total; 1360 } 1361 1362 /** 1363 * Checks if the specified collection/array/iterator is empty. 1364 * <p> 1365 * This method can handles objects as follows 1366 * <ul> 1367 * <li>Collection - via collection isEmpty 1368 * <li>Map - via map isEmpty 1369 * <li>Array - using array size 1370 * <li>Iterator - via hasNext 1371 * <li>Enumeration - via hasMoreElements 1372 * </ul> 1373 * <p> 1374 * Note: This method is named to avoid clashing with 1375 * {@link #isEmpty(Collection)}. 1376 * 1377 * @param object the object to get the size of, may be null 1378 * @return true if empty or null 1379 * @throws IllegalArgumentException thrown if object is not recognised 1380 * @since 3.2 1381 */ 1382 public static boolean sizeIsEmpty(final Object object) { 1383 if (object == null) { 1384 return true; 1385 } else if (object instanceof Collection<?>) { 1386 return ((Collection<?>) object).isEmpty(); 1387 } else if (object instanceof Map<?, ?>) { 1388 return ((Map<?, ?>) object).isEmpty(); 1389 } else if (object instanceof Object[]) { 1390 return ((Object[]) object).length == 0; 1391 } else if (object instanceof Iterator<?>) { 1392 return ((Iterator<?>) object).hasNext() == false; 1393 } else if (object instanceof Enumeration<?>) { 1394 return ((Enumeration<?>) object).hasMoreElements() == false; 1395 } else { 1396 try { 1397 return Array.getLength(object) == 0; 1398 } catch (final IllegalArgumentException ex) { 1399 throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName()); 1400 } 1401 } 1402 } 1403 1404 //----------------------------------------------------------------------- 1405 /** 1406 * Null-safe check if the specified collection is empty. 1407 * <p> 1408 * Null returns true. 1409 * 1410 * @param coll the collection to check, may be null 1411 * @return true if empty or null 1412 * @since 3.2 1413 */ 1414 public static boolean isEmpty(final Collection<?> coll) { 1415 return coll == null || coll.isEmpty(); 1416 } 1417 1418 /** 1419 * Null-safe check if the specified collection is not empty. 1420 * <p> 1421 * Null returns false. 1422 * 1423 * @param coll the collection to check, may be null 1424 * @return true if non-null and non-empty 1425 * @since 3.2 1426 */ 1427 public static boolean isNotEmpty(final Collection<?> coll) { 1428 return !isEmpty(coll); 1429 } 1430 1431 //----------------------------------------------------------------------- 1432 /** 1433 * Reverses the order of the given array. 1434 * 1435 * @param array the array to reverse 1436 */ 1437 public static void reverseArray(final Object[] array) { 1438 int i = 0; 1439 int j = array.length - 1; 1440 Object tmp; 1441 1442 while (j > i) { 1443 tmp = array[j]; 1444 array[j] = array[i]; 1445 array[i] = tmp; 1446 j--; 1447 i++; 1448 } 1449 } 1450 1451 /** 1452 * Returns true if no more elements can be added to the Collection. 1453 * <p> 1454 * This method uses the {@link BoundedCollection} interface to determine the 1455 * full status. If the collection does not implement this interface then 1456 * false is returned. 1457 * <p> 1458 * The collection does not have to implement this interface directly. 1459 * If the collection has been decorated using the decorators subpackage 1460 * then these will be removed to access the BoundedCollection. 1461 * 1462 * @param coll the collection to check 1463 * @return true if the BoundedCollection is full 1464 * @throws NullPointerException if the collection is null 1465 */ 1466 public static boolean isFull(final Collection<? extends Object> coll) { 1467 if (coll == null) { 1468 throw new NullPointerException("The collection must not be null"); 1469 } 1470 if (coll instanceof BoundedCollection) { 1471 return ((BoundedCollection<?>) coll).isFull(); 1472 } 1473 try { 1474 final BoundedCollection<?> bcoll = 1475 UnmodifiableBoundedCollection.unmodifiableBoundedCollection(coll); 1476 return bcoll.isFull(); 1477 } catch (final IllegalArgumentException ex) { 1478 return false; 1479 } 1480 } 1481 1482 /** 1483 * Get the maximum number of elements that the Collection can contain. 1484 * <p> 1485 * This method uses the {@link BoundedCollection} interface to determine the 1486 * maximum size. If the collection does not implement this interface then 1487 * -1 is returned. 1488 * <p> 1489 * The collection does not have to implement this interface directly. 1490 * If the collection has been decorated using the decorators subpackage 1491 * then these will be removed to access the BoundedCollection. 1492 * 1493 * @param coll the collection to check 1494 * @return the maximum size of the BoundedCollection, -1 if no maximum size 1495 * @throws NullPointerException if the collection is null 1496 */ 1497 public static int maxSize(final Collection<? extends Object> coll) { 1498 if (coll == null) { 1499 throw new NullPointerException("The collection must not be null"); 1500 } 1501 if (coll instanceof BoundedCollection) { 1502 return ((BoundedCollection<?>) coll).maxSize(); 1503 } 1504 try { 1505 final BoundedCollection<?> bcoll = 1506 UnmodifiableBoundedCollection.unmodifiableBoundedCollection(coll); 1507 return bcoll.maxSize(); 1508 } catch (final IllegalArgumentException ex) { 1509 return -1; 1510 } 1511 } 1512 1513 //----------------------------------------------------------------------- 1514 /** 1515 * Merges two sorted Collections, a and b, into a single, sorted List 1516 * such that the natural ordering of the elements is retained. 1517 * <p> 1518 * Uses the standard O(n) merge algorithm for combining two sorted lists. 1519 * 1520 * @param <O> the element type 1521 * @param a the first collection, must not be null 1522 * @param b the second collection, must not be null 1523 * @return a new sorted List, containing the elements of Collection a and b 1524 * @throws IllegalArgumentException if either collection is null 1525 * @since 4.0 1526 */ 1527 public static <O extends Comparable<? super O>> List<O> collate(Iterable<? extends O> a, 1528 Iterable<? extends O> b) { 1529 return collate(a, b, ComparatorUtils.<O>naturalComparator(), true); 1530 } 1531 1532 /** 1533 * Merges two sorted Collections, a and b, into a single, sorted List 1534 * such that the natural ordering of the elements is retained. 1535 * <p> 1536 * Uses the standard O(n) merge algorithm for combining two sorted lists. 1537 * 1538 * @param <O> the element type 1539 * @param a the first collection, must not be null 1540 * @param b the second collection, must not be null 1541 * @param includeDuplicates if {@code true} duplicate elements will be retained, otherwise 1542 * they will be removed in the output collection 1543 * @return a new sorted List, containing the elements of Collection a and b 1544 * @throws IllegalArgumentException if either collection is null 1545 * @since 4.0 1546 */ 1547 public static <O extends Comparable<? super O>> List<O> collate(final Iterable<? extends O> a, 1548 final Iterable<? extends O> b, 1549 final boolean includeDuplicates) { 1550 return collate(a, b, ComparatorUtils.<O>naturalComparator(), includeDuplicates); 1551 } 1552 1553 /** 1554 * Merges two sorted Collections, a and b, into a single, sorted List 1555 * such that the ordering of the elements according to Comparator c is retained. 1556 * <p> 1557 * Uses the standard O(n) merge algorithm for combining two sorted lists. 1558 * 1559 * @param <O> the element type 1560 * @param a the first collection, must not be null 1561 * @param b the second collection, must not be null 1562 * @param c the comparator to use for the merge. 1563 * @return a new sorted List, containing the elements of Collection a and b 1564 * @throws IllegalArgumentException if either collection or the comparator is null 1565 * @since 4.0 1566 */ 1567 public static <O> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b, 1568 final Comparator<? super O> c) { 1569 return collate(a, b, c, true); 1570 } 1571 1572 /** 1573 * Merges two sorted Collections, a and b, into a single, sorted List 1574 * such that the ordering of the elements according to Comparator c is retained. 1575 * <p> 1576 * Uses the standard O(n) merge algorithm for combining two sorted lists. 1577 * 1578 * @param <O> the element type 1579 * @param a the first collection, must not be null 1580 * @param b the second collection, must not be null 1581 * @param c the comparator to use for the merge. 1582 * @param includeDuplicates if {@code true} duplicate elements will be retained, otherwise 1583 * they will be removed in the output collection 1584 * @return a new sorted List, containing the elements of Collection a and b 1585 * @throws IllegalArgumentException if either collection or the comparator is null 1586 * @since 4.0 1587 */ 1588 public static <O> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b, 1589 final Comparator<? super O> c, final boolean includeDuplicates) { 1590 1591 if (a == null || b == null) { 1592 throw new IllegalArgumentException("The collections must not be null"); 1593 } 1594 if (c == null) { 1595 throw new IllegalArgumentException("The comparator must not be null"); 1596 } 1597 1598 // if both Iterables are a Collection, we can estimate the size 1599 final int totalSize = a instanceof Collection<?> && b instanceof Collection<?> ? 1600 Math.max(1, ((Collection<?>) a).size() + ((Collection<?>) b).size()) : 10; 1601 1602 final Iterator<O> iterator = new CollatingIterator<O>(c, a.iterator(), b.iterator()); 1603 if (includeDuplicates) { 1604 return IteratorUtils.toList(iterator, totalSize); 1605 } else { 1606 final ArrayList<O> mergedList = new ArrayList<O>(totalSize); 1607 1608 O lastItem = null; 1609 while (iterator.hasNext()) { 1610 final O item = iterator.next(); 1611 if (lastItem == null || !lastItem.equals(item)) { 1612 mergedList.add(item); 1613 } 1614 lastItem = item; 1615 } 1616 1617 mergedList.trimToSize(); 1618 return mergedList; 1619 } 1620 } 1621 1622 //----------------------------------------------------------------------- 1623 1624 /** 1625 * Returns a {@link Collection} of all the permutations of the input collection. 1626 * <p> 1627 * NOTE: the number of permutations of a given collection is equal to n!, where 1628 * n is the size of the collection. Thus, the resulting collection will become 1629 * <b>very</b> large for collections > 10 (e.g. 10! = 3628800, 15! = 1307674368000). 1630 * <p> 1631 * For larger collections it is advised to use a {@link PermutationIterator} to 1632 * iterate over all permutations. 1633 * 1634 * @see PermutationIterator 1635 * 1636 * @param <E> the element type 1637 * @param collection the collection to create permutations for, may not be null 1638 * @return an unordered collection of all permutations of the input collection 1639 * @throws NullPointerException if collection is null 1640 * @since 4.0 1641 */ 1642 public static <E> Collection<List<E>> permutations(final Collection<E> collection) { 1643 final PermutationIterator<E> it = new PermutationIterator<E>(collection); 1644 final Collection<List<E>> result = new LinkedList<List<E>>(); 1645 while (it.hasNext()) { 1646 result.add(it.next()); 1647 } 1648 return result; 1649 } 1650 1651 //----------------------------------------------------------------------- 1652 /** 1653 * Returns a collection containing all the elements in <code>collection</code> 1654 * that are also in <code>retain</code>. The cardinality of an element <code>e</code> 1655 * in the returned collection is the same as the cardinality of <code>e</code> 1656 * in <code>collection</code> unless <code>retain</code> does not contain <code>e</code>, in which 1657 * case the cardinality is zero. This method is useful if you do not wish to modify 1658 * the collection <code>c</code> and thus cannot call <code>c.retainAll(retain);</code>. 1659 * 1660 * @param <C> the type of object the {@link Collection} contains 1661 * @param collection the collection whose contents are the target of the #retailAll operation 1662 * @param retain the collection containing the elements to be retained in the returned collection 1663 * @return a <code>Collection</code> containing all the elements of <code>collection</code> 1664 * that occur at least once in <code>retain</code>. 1665 * @throws NullPointerException if either parameter is null 1666 * @since 3.2 1667 */ 1668 public static <C> Collection<C> retainAll(final Collection<C> collection, final Collection<?> retain) { 1669 return ListUtils.retainAll(collection, retain); 1670 } 1671 1672 /** 1673 * Removes the elements in <code>remove</code> from <code>collection</code>. That is, this 1674 * method returns a collection containing all the elements in <code>c</code> 1675 * that are not in <code>remove</code>. The cardinality of an element <code>e</code> 1676 * in the returned collection is the same as the cardinality of <code>e</code> 1677 * in <code>collection</code> unless <code>remove</code> contains <code>e</code>, in which 1678 * case the cardinality is zero. This method is useful if you do not wish to modify 1679 * the collection <code>c</code> and thus cannot call <code>collection.removeAll(remove);</code>. 1680 * 1681 * @param <E> the type of object the {@link Collection} contains 1682 * @param collection the collection from which items are removed (in the returned collection) 1683 * @param remove the items to be removed from the returned <code>collection</code> 1684 * @return a <code>Collection</code> containing all the elements of <code>collection</code> except 1685 * any elements that also occur in <code>remove</code>. 1686 * @throws NullPointerException if either parameter is null 1687 * @since 4.0 (method existed in 3.2 but was completely broken) 1688 */ 1689 public static <E> Collection<E> removeAll(final Collection<E> collection, final Collection<?> remove) { 1690 return ListUtils.removeAll(collection, remove); 1691 } 1692 1693 //----------------------------------------------------------------------- 1694 /** 1695 * Returns a synchronized collection backed by the given collection. 1696 * <p> 1697 * You must manually synchronize on the returned buffer's iterator to 1698 * avoid non-deterministic behavior: 1699 * 1700 * <pre> 1701 * Collection c = CollectionUtils.synchronizedCollection(myCollection); 1702 * synchronized (c) { 1703 * Iterator i = c.iterator(); 1704 * while (i.hasNext()) { 1705 * process (i.next()); 1706 * } 1707 * } 1708 * </pre> 1709 * 1710 * This method uses the implementation in the decorators subpackage. 1711 * 1712 * @param <C> the type of object the {@link Collection} contains 1713 * @param collection the collection to synchronize, must not be null 1714 * @return a synchronized collection backed by the given collection 1715 * @throws IllegalArgumentException if the collection is null 1716 */ 1717 public static <C> Collection<C> synchronizedCollection(final Collection<C> collection) { 1718 return SynchronizedCollection.synchronizedCollection(collection); 1719 } 1720 1721 /** 1722 * Returns an unmodifiable collection backed by the given collection. 1723 * <p> 1724 * This method uses the implementation in the decorators subpackage. 1725 * 1726 * @param <C> the type of object the {@link Collection} contains 1727 * @param collection the collection to make unmodifiable, must not be null 1728 * @return an unmodifiable collection backed by the given collection 1729 * @throws IllegalArgumentException if the collection is null 1730 */ 1731 public static <C> Collection<C> unmodifiableCollection(final Collection<? extends C> collection) { 1732 return UnmodifiableCollection.unmodifiableCollection(collection); 1733 } 1734 1735 /** 1736 * Returns a predicated (validating) collection backed by the given collection. 1737 * <p> 1738 * Only objects that pass the test in the given predicate can be added to the collection. 1739 * Trying to add an invalid object results in an IllegalArgumentException. 1740 * It is important not to use the original collection after invoking this method, 1741 * as it is a backdoor for adding invalid objects. 1742 * 1743 * @param collection the collection to predicate, must not be null 1744 * @param predicate the predicate for the collection, must not be null 1745 * @param <C> the type of objects in the Collection. 1746 * @return a predicated collection backed by the given collection 1747 * @throws IllegalArgumentException if the Collection is null 1748 */ 1749 public static <C> Collection<C> predicatedCollection(final Collection<C> collection, 1750 final Predicate<? super C> predicate) { 1751 return PredicatedCollection.predicatedCollection(collection, predicate); 1752 } 1753 1754 /** 1755 * Returns a transformed bag backed by the given collection. 1756 * <p> 1757 * Each object is passed through the transformer as it is added to the 1758 * Collection. It is important not to use the original collection after invoking this 1759 * method, as it is a backdoor for adding untransformed objects. 1760 * <p> 1761 * Existing entries in the specified collection will not be transformed. 1762 * If you want that behaviour, see {@link TransformedCollection#transformedCollection}. 1763 * 1764 * @param <E> the type of object the {@link Collection} contains 1765 * @param collection the collection to predicate, must not be null 1766 * @param transformer the transformer for the collection, must not be null 1767 * @return a transformed collection backed by the given collection 1768 * @throws IllegalArgumentException if the Collection or Transformer is null 1769 */ 1770 public static <E> Collection<E> transformingCollection(final Collection<E> collection, 1771 final Transformer<? super E, ? extends E> transformer) { 1772 return TransformedCollection.transformingCollection(collection, transformer); 1773 } 1774 1775 /** 1776 * Extract the lone element of the specified Collection. 1777 * @param <E> collection type 1778 * @param collection to read 1779 * @return sole member of collection 1780 * @throws IllegalArgumentException if collection is null/empty or contains more than one element 1781 * @since 4.0 1782 */ 1783 public static <E> E extractSingleton(final Collection<E> collection) { 1784 if (collection == null || collection.size() != 1) { 1785 throw new IllegalArgumentException("Can extract singleton only when collection size == 1"); 1786 } 1787 return collection.iterator().next(); 1788 } 1789}