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