1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.collections4; 18 19 import java.util.AbstractList; 20 import java.util.ArrayList; 21 import java.util.Collection; 22 import java.util.Collections; 23 import java.util.HashSet; 24 import java.util.Iterator; 25 import java.util.List; 26 import java.util.Objects; 27 28 import org.apache.commons.collections4.bag.HashBag; 29 import org.apache.commons.collections4.functors.DefaultEquator; 30 import org.apache.commons.collections4.list.FixedSizeList; 31 import org.apache.commons.collections4.list.LazyList; 32 import org.apache.commons.collections4.list.PredicatedList; 33 import org.apache.commons.collections4.list.TransformedList; 34 import org.apache.commons.collections4.list.UnmodifiableList; 35 import org.apache.commons.collections4.sequence.CommandVisitor; 36 import org.apache.commons.collections4.sequence.EditScript; 37 import org.apache.commons.collections4.sequence.SequencesComparator; 38 39 /** 40 * Provides utility methods and decorators for {@link List} instances. 41 * 42 * @since 1.0 43 */ 44 public class ListUtils { 45 46 /** 47 * A simple wrapper to use a CharSequence as List. 48 */ 49 private static final class CharSequenceAsList extends AbstractList<Character> { 50 private final CharSequence sequence; 51 52 CharSequenceAsList(final CharSequence sequence) { 53 this.sequence = sequence; 54 } 55 56 @Override 57 public Character get(final int index) { 58 return Character.valueOf(sequence.charAt(index)); 59 } 60 61 @Override 62 public int size() { 63 return sequence.length(); 64 } 65 } 66 67 /** 68 * A helper class used to construct the longest common subsequence. 69 */ 70 private static final class LcsVisitor<E> implements CommandVisitor<E> { 71 private final ArrayList<E> sequence; 72 73 LcsVisitor() { 74 sequence = new ArrayList<>(); 75 } 76 77 public List<E> getSubSequence() { 78 return sequence; 79 } 80 81 @Override 82 public void visitDeleteCommand(final E object) { 83 // noop 84 } 85 86 @Override 87 public void visitInsertCommand(final E object) { 88 // noop 89 } 90 91 @Override 92 public void visitKeepCommand(final E object) { 93 sequence.add(object); 94 } 95 } 96 97 /** 98 * Provides a partition view on a {@link List}. 99 * @since 4.0 100 */ 101 private static final class Partition<T> extends AbstractList<List<T>> { 102 private final List<T> list; 103 private final int size; 104 105 private Partition(final List<T> list, final int size) { 106 this.list = list; 107 this.size = size; 108 } 109 110 @Override 111 public List<T> get(final int index) { 112 final int listSize = size(); 113 if (index < 0) { 114 throw new IndexOutOfBoundsException("Index " + index + " must not be negative"); 115 } 116 if (index >= listSize) { 117 throw new IndexOutOfBoundsException("Index " + index + " must be less than size " + 118 listSize); 119 } 120 final int start = index * size; 121 final int end = Math.min(start + size, list.size()); 122 return list.subList(start, end); 123 } 124 125 @Override 126 public boolean isEmpty() { 127 return list.isEmpty(); 128 } 129 130 @Override 131 public int size() { 132 return (int) Math.ceil((double) list.size() / (double) size); 133 } 134 } 135 136 /** 137 * Returns either the passed in list, or if the list is {@code null}, 138 * the value of {@code defaultList}. 139 * 140 * @param <T> the element type 141 * @param list the list, possibly {@code null} 142 * @param defaultList the returned values if list is {@code null} 143 * @return an empty list if the argument is {@code null} 144 * @since 4.0 145 */ 146 public static <T> List<T> defaultIfNull(final List<T> list, final List<T> defaultList) { 147 return list == null ? defaultList : list; 148 } 149 150 /** 151 * Returns an immutable empty list if the argument is {@code null}, 152 * or the argument itself otherwise. 153 * 154 * @param <T> the element type 155 * @param list the list, possibly {@code null} 156 * @return an empty list if the argument is {@code null} 157 */ 158 public static <T> List<T> emptyIfNull(final List<T> list) { 159 return list == null ? Collections.<T>emptyList() : list; 160 } 161 162 /** 163 * Returns a fixed-sized list backed by the given list. 164 * Elements may not be added or removed from the returned list, but 165 * existing elements can be changed (for instance, via the 166 * {@link List#set(int, Object)} method). 167 * 168 * @param <E> the element type 169 * @param list the list whose size to fix, must not be null 170 * @return a fixed-size list backed by that list 171 * @throws NullPointerException if the List is null 172 */ 173 public static <E> List<E> fixedSizeList(final List<E> list) { 174 return FixedSizeList.fixedSizeList(list); 175 } 176 177 /** 178 * Gets the first element of a list. 179 * <p> 180 * Shorthand for {@code list.get(0)} 181 * </p> 182 * 183 * @param <T> The list type. 184 * @param list The list. 185 * @return the first element of a list. 186 * @see List#get(int) 187 * @since 4.5.0-M1 188 */ 189 public static <T> T getFirst(final List<T> list) { 190 return Objects.requireNonNull(list, "list").get(0); 191 } 192 193 /** 194 * Gets the last element of a list. 195 * <p> 196 * Shorthand for {@code list.get(list.size() - 1)} 197 * </p> 198 * 199 * @param <T> The list type. 200 * @param list The list. 201 * @return the last element of a list. 202 * @see List#get(int) 203 * @since 4.5.0-M1 204 */ 205 public static <T> T getLast(final List<T> list) { 206 return Objects.requireNonNull(list, "list").get(list.size() - 1); 207 } 208 209 /** 210 * Generates a hash code using the algorithm specified in 211 * {@link java.util.List#hashCode()}. 212 * <p> 213 * This method is useful for implementing {@code List} when you cannot 214 * extend AbstractList. The method takes Collection instances to enable other 215 * collection types to use the List implementation algorithm. 216 * </p> 217 * 218 * @see java.util.List#hashCode() 219 * @param list the list to generate the hashCode for, may be null 220 * @return the hash code 221 */ 222 public static int hashCodeForList(final Collection<?> list) { 223 if (list == null) { 224 return 0; 225 } 226 int hashCode = 1; 227 228 for (final Object obj : list) { 229 hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); 230 } 231 return hashCode; 232 } 233 234 /** 235 * Finds the first index in the given List which matches the given predicate. 236 * <p> 237 * If the input List or predicate is null, or no element of the List 238 * matches the predicate, -1 is returned. 239 * </p> 240 * 241 * @param <E> the element type 242 * @param list the List to search, may be null 243 * @param predicate the predicate to use, may be null 244 * @return the first index of an Object in the List which matches the predicate or -1 if none could be found 245 */ 246 public static <E> int indexOf(final List<E> list, final Predicate<E> predicate) { 247 if (list != null && predicate != null) { 248 for (int i = 0; i < list.size(); i++) { 249 final E item = list.get(i); 250 if (predicate.test(item)) { 251 return i; 252 } 253 } 254 } 255 return CollectionUtils.INDEX_NOT_FOUND; 256 } 257 258 /** 259 * Returns a new list containing all elements that are contained in 260 * both given lists. 261 * 262 * @param <E> the element type 263 * @param list1 the first list 264 * @param list2 the second list 265 * @return the intersection of those two lists 266 * @throws NullPointerException if either list is null 267 */ 268 public static <E> List<E> intersection(final List<? extends E> list1, final List<? extends E> list2) { 269 final List<E> result = new ArrayList<>(); 270 271 List<? extends E> smaller = list1; 272 List<? extends E> larger = list2; 273 if (list1.size() > list2.size()) { 274 smaller = list2; 275 larger = list1; 276 } 277 278 final HashSet<E> hashSet = new HashSet<>(smaller); 279 280 for (final E e : larger) { 281 if (hashSet.contains(e)) { 282 result.add(e); 283 hashSet.remove(e); 284 } 285 } 286 return result; 287 } 288 289 /** 290 * Tests two lists for value-equality as per the equality contract in 291 * {@link java.util.List#equals(Object)}. 292 * <p> 293 * This method is useful for implementing {@code List} when you cannot 294 * extend AbstractList. The method takes Collection instances to enable other 295 * collection types to use the List implementation algorithm. 296 * </p> 297 * <p> 298 * The relevant text (slightly paraphrased as this is a static method) is: 299 * </p> 300 * <blockquote> 301 * Compares the two list objects for equality. Returns 302 * {@code true} if and only if both 303 * lists have the same size, and all corresponding pairs of elements in 304 * the two lists are <em>equal</em>. (Two elements {@code e1} and 305 * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null : 306 * e1.equals(e2))}.) In other words, two lists are defined to be 307 * equal if they contain the same elements in the same order. This 308 * definition ensures that the equals method works properly across 309 * different implementations of the {@code List} interface. 310 * </blockquote> 311 * <p> 312 * <strong>Note:</strong> The behavior of this method is undefined if the lists are 313 * modified during the equals comparison. 314 * </p> 315 * 316 * @see java.util.List 317 * @param list1 the first list, may be null 318 * @param list2 the second list, may be null 319 * @return whether the lists are equal by value comparison 320 */ 321 public static boolean isEqualList(final Collection<?> list1, final Collection<?> list2) { 322 if (list1 == list2) { 323 return true; 324 } 325 if (list1 == null || list2 == null || list1.size() != list2.size()) { 326 return false; 327 } 328 329 final Iterator<?> it1 = list1.iterator(); 330 final Iterator<?> it2 = list2.iterator(); 331 332 while (it1.hasNext() && it2.hasNext()) { 333 final Object obj1 = it1.next(); 334 final Object obj2 = it2.next(); 335 336 if (!Objects.equals(obj1, obj2)) { 337 return false; 338 } 339 } 340 341 return !(it1.hasNext() || it2.hasNext()); 342 } 343 344 /** 345 * Returns a "lazy" list whose elements will be created on demand. 346 * <p> 347 * When the index passed to the returned list's {@link List#get(int) get} 348 * method is greater than the list's size, then the factory will be used 349 * to create a new object and that object will be inserted at that index. 350 * </p> 351 * <p> 352 * For instance: 353 * </p> 354 * <pre> 355 * Factory<Date> factory = new Factory<Date>() { 356 * public Date create() { 357 * return new Date(); 358 * } 359 * } 360 * List<Date> lazy = ListUtils.lazyList(new ArrayList<Date>(), factory); 361 * Date date = lazy.get(3); 362 * </pre> 363 * <p> 364 * After the above code is executed, {@code date} will refer to 365 * a new {@code Date} instance. Furthermore, that {@code Date} 366 * instance is the fourth element in the list. The first, second, 367 * and third element are all set to {@code null}. 368 * </p> 369 * 370 * @param <E> the element type 371 * @param list the list to make lazy, must not be null 372 * @param factory the factory for creating new objects, must not be null 373 * @return a lazy list backed by the given list 374 * @throws NullPointerException if the List or Factory is null 375 */ 376 public static <E> List<E> lazyList(final List<E> list, final Factory<? extends E> factory) { 377 return LazyList.lazyList(list, factory); 378 } 379 380 /** 381 * Returns a "lazy" list whose elements will be created on demand. 382 * <p> 383 * When the index passed to the returned list's {@link List#get(int) get} 384 * method is greater than the list's size, then the transformer will be used 385 * to create a new object and that object will be inserted at that index. 386 * </p> 387 * <p> 388 * For instance: 389 * </p> 390 * <pre> 391 * List<Integer> hours = Arrays.asList(7, 5, 8, 2); 392 * Transformer<Integer,Date> transformer = input -> LocalDateTime.now().withHour(hours.get(input)); 393 * List<LocalDateTime> lazy = ListUtils.lazyList(new ArrayList<LocalDateTime>(), transformer); 394 * Date date = lazy.get(3); 395 * </pre> 396 * <p> 397 * After the above code is executed, {@code date} will refer to 398 * a new {@code Date} instance. Furthermore, that {@code Date} 399 * instance is the fourth element in the list. The first, second, 400 * and third element are all set to {@code null}. 401 * </p> 402 * 403 * @param <E> the element type 404 * @param list the list to make lazy, must not be null 405 * @param transformer the transformer for creating new objects, must not be null 406 * @return a lazy list backed by the given list 407 * @throws NullPointerException if the List or Transformer is null 408 */ 409 public static <E> List<E> lazyList(final List<E> list, final Transformer<Integer, ? extends E> transformer) { 410 return LazyList.lazyList(list, transformer); 411 } 412 413 /** 414 * Returns the longest common subsequence (LCS) of two {@link CharSequence} objects. 415 * <p> 416 * This is a convenience method for using {@link #longestCommonSubsequence(List, List)} 417 * with {@link CharSequence} instances. 418 * </p> 419 * 420 * @param charSequenceA the first sequence 421 * @param charSequenceB the second sequence 422 * @return the longest common subsequence as {@link String} 423 * @throws NullPointerException if either sequence is {@code null} 424 * @since 4.0 425 */ 426 public static String longestCommonSubsequence(final CharSequence charSequenceA, final CharSequence charSequenceB) { 427 Objects.requireNonNull(charSequenceA, "charSequenceA"); 428 Objects.requireNonNull(charSequenceB, "charSequenceB"); 429 final List<Character> lcs = longestCommonSubsequence(new CharSequenceAsList(charSequenceA), 430 new CharSequenceAsList(charSequenceB)); 431 final StringBuilder sb = new StringBuilder(); 432 for (final Character ch : lcs) { 433 sb.append(ch); 434 } 435 return sb.toString(); 436 } 437 438 /** 439 * Returns the longest common subsequence (LCS) of two sequences (lists). 440 * 441 * @param <E> the element type 442 * @param a the first list 443 * @param b the second list 444 * @return the longest common subsequence 445 * @throws NullPointerException if either list is {@code null} 446 * @since 4.0 447 */ 448 public static <E> List<E> longestCommonSubsequence(final List<E> a, final List<E> b) { 449 return longestCommonSubsequence(a, b, DefaultEquator.defaultEquator()); 450 } 451 452 /** 453 * Returns the longest common subsequence (LCS) of two sequences (lists). 454 * 455 * @param <E> the element type 456 * @param listA the first list 457 * @param listB the second list 458 * @param equator the equator used to test object equality 459 * @return the longest common subsequence 460 * @throws NullPointerException if either list or the equator is {@code null} 461 * @since 4.0 462 */ 463 public static <E> List<E> longestCommonSubsequence(final List<E> listA, final List<E> listB, 464 final Equator<? super E> equator) { 465 Objects.requireNonNull(listA, "listA"); 466 Objects.requireNonNull(listB, "listB"); 467 Objects.requireNonNull(equator, "equator"); 468 469 final SequencesComparator<E> comparator = new SequencesComparator<>(listA, listB, equator); 470 final EditScript<E> script = comparator.getScript(); 471 final LcsVisitor<E> visitor = new LcsVisitor<>(); 472 script.visit(visitor); 473 return visitor.getSubSequence(); 474 } 475 476 /** 477 * Returns consecutive {@link List#subList(int, int) sublists} of a 478 * list, each of the same size (the final list may be smaller). For example, 479 * partitioning a list containing {@code [a, b, c, d, e]} with a partition 480 * size of 3 yields {@code [[a, b, c], [d, e]]} -- an outer list containing 481 * two inner lists of three and two elements, all in the original order. 482 * <p> 483 * The outer list is unmodifiable, but reflects the latest state of the 484 * source list. The inner lists are sublist views of the original list, 485 * produced on demand using {@link List#subList(int, int)}, and are subject 486 * to all the usual caveats about modification as explained in that API. 487 * </p> 488 * <p> 489 * Adapted from https://github.com/google/guava 490 * </p> 491 * 492 * @param <T> the element type 493 * @param list the list to return consecutive sublists of 494 * @param size the desired size of each sublist (the last may be smaller) 495 * @return a list of consecutive sublists 496 * @throws NullPointerException if list is null 497 * @throws IllegalArgumentException if size is not strictly positive 498 * @since 4.0 499 */ 500 public static <T> List<List<T>> partition(final List<T> list, final int size) { 501 Objects.requireNonNull(list, "list"); 502 if (size <= 0) { 503 throw new IllegalArgumentException("Size must be greater than 0"); 504 } 505 return new Partition<>(list, size); 506 } 507 508 /** 509 * Returns a predicated (validating) list backed by the given list. 510 * <p> 511 * Only objects that pass the test in the given predicate can be added to the list. 512 * Trying to add an invalid object results in an IllegalArgumentException. 513 * It is important not to use the original list after invoking this method, 514 * as it is a backdoor for adding invalid objects. 515 * </p> 516 * 517 * @param <E> the element type 518 * @param list the list to predicate, must not be null 519 * @param predicate the predicate for the list, must not be null 520 * @return a predicated list backed by the given list 521 * @throws NullPointerException if the List or Predicate is null 522 */ 523 public static <E> List<E> predicatedList(final List<E> list, final Predicate<E> predicate) { 524 return PredicatedList.predicatedList(list, predicate); 525 } 526 527 /** 528 * Removes the elements in {@code remove} from {@code collection}. That is, this 529 * method returns a list containing all the elements in {@code collection} 530 * that are not in {@code remove}. The cardinality of an element {@code e} 531 * in the returned collection is the same as the cardinality of {@code e} 532 * in {@code collection} unless {@code remove} contains {@code e}, in which 533 * case the cardinality is zero. This method is useful if you do not wish to modify 534 * {@code collection} and thus cannot call {@code collection.removeAll(remove);}. 535 * <p> 536 * This implementation iterates over {@code collection}, checking each element in 537 * turn to see if it's contained in {@code remove}. If it's not contained, it's added 538 * to the returned list. As a consequence, it is advised to use a collection type for 539 * {@code remove} that provides a fast (e.g. O(1)) implementation of 540 * {@link Collection#contains(Object)}. 541 * </p> 542 * 543 * @param <E> the element type 544 * @param collection the collection from which items are removed (in the returned collection) 545 * @param remove the items to be removed from the returned {@code collection} 546 * @return a {@code List} containing all the elements of {@code c} except 547 * any elements that also occur in {@code remove}. 548 * @throws NullPointerException if either parameter is null 549 * @since 3.2 550 */ 551 public static <E> List<E> removeAll(final Collection<E> collection, final Collection<?> remove) { 552 Objects.requireNonNull(collection, "collection"); 553 Objects.requireNonNull(remove, "remove"); 554 final List<E> list = new ArrayList<>(); 555 for (final E obj : collection) { 556 if (!remove.contains(obj)) { 557 list.add(obj); 558 } 559 } 560 return list; 561 } 562 563 /** 564 * Returns a List containing all the elements in {@code collection} 565 * that are also in {@code retain}. The cardinality of an element {@code e} 566 * in the returned list is the same as the cardinality of {@code e} 567 * in {@code collection} unless {@code retain} does not contain {@code e}, in which 568 * case the cardinality is zero. This method is useful if you do not wish to modify 569 * the collection {@code c} and thus cannot call {@code collection.retainAll(retain);}. 570 * <p> 571 * This implementation iterates over {@code collection}, checking each element in 572 * turn to see if it's contained in {@code retain}. If it's contained, it's added 573 * to the returned list. As a consequence, it is advised to use a collection type for 574 * {@code retain} that provides a fast (e.g. O(1)) implementation of 575 * {@link Collection#contains(Object)}. 576 * </p> 577 * 578 * @param <E> the element type 579 * @param collection the collection whose contents are the target of the #retailAll operation 580 * @param retain the collection containing the elements to be retained in the returned collection 581 * @return a {@code List} containing all the elements of {@code c} 582 * that occur at least once in {@code retain}. 583 * @throws NullPointerException if either parameter is null 584 * @since 3.2 585 */ 586 public static <E> List<E> retainAll(final Collection<E> collection, final Collection<?> retain) { 587 final List<E> list = new ArrayList<>(Math.min(collection.size(), retain.size())); 588 589 for (final E obj : collection) { 590 if (retain.contains(obj)) { 591 list.add(obj); 592 } 593 } 594 return list; 595 } 596 597 /** 598 * Selects all elements from input collection which match the given 599 * predicate into an output list. 600 * <p> 601 * A {@code null} predicate matches no elements. 602 * </p> 603 * 604 * @param <E> the element type 605 * @param inputCollection the collection to get the input from, may not be null 606 * @param predicate the predicate to use, may be null 607 * @return the elements matching the predicate (new list) 608 * @throws NullPointerException if the input list is null 609 * @since 4.0 610 * @see CollectionUtils#select(Iterable, Predicate) 611 */ 612 public static <E> List<E> select(final Collection<? extends E> inputCollection, 613 final Predicate<? super E> predicate) { 614 return CollectionUtils.select(inputCollection, predicate, new ArrayList<>(inputCollection.size())); 615 } 616 617 /** 618 * Selects all elements from inputCollection which don't match the given 619 * predicate into an output collection. 620 * <p> 621 * If the input predicate is {@code null}, the result is an empty list. 622 * </p> 623 * 624 * @param <E> the element type 625 * @param inputCollection the collection to get the input from, may not be null 626 * @param predicate the predicate to use, may be null 627 * @return the elements <strong>not</strong> matching the predicate (new list) 628 * @throws NullPointerException if the input collection is null 629 * @since 4.0 630 * @see CollectionUtils#selectRejected(Iterable, Predicate) 631 */ 632 public static <E> List<E> selectRejected(final Collection<? extends E> inputCollection, 633 final Predicate<? super E> predicate) { 634 return CollectionUtils.selectRejected(inputCollection, predicate, new ArrayList<>(inputCollection.size())); 635 } 636 637 /** 638 * Subtracts all elements in the second list from the first list, 639 * placing the results in a new list. 640 * <p> 641 * This differs from {@link List#removeAll(Collection)} in that 642 * cardinality is respected; if <Code>list1</Code> contains two 643 * occurrences of <Code>null</Code> and <Code>list2</Code> only 644 * contains one occurrence, then the returned list will still contain 645 * one occurrence. 646 * </p> 647 * 648 * @param <E> the element type 649 * @param list1 the list to subtract from 650 * @param list2 the list to subtract 651 * @return a new list containing the results 652 * @throws NullPointerException if either list is null 653 */ 654 public static <E> List<E> subtract(final List<E> list1, final List<? extends E> list2) { 655 final ArrayList<E> result = new ArrayList<>(); 656 final HashBag<E> bag = new HashBag<>(list2); 657 for (final E e : list1) { 658 if (!bag.remove(e, 1)) { 659 result.add(e); 660 } 661 } 662 return result; 663 } 664 665 /** 666 * Returns the sum of the given lists. This is their intersection 667 * subtracted from their union. 668 * 669 * @param <E> the element type 670 * @param list1 the first list 671 * @param list2 the second list 672 * @return a new list containing the sum of those lists 673 * @throws NullPointerException if either list is null 674 */ 675 public static <E> List<E> sum(final List<? extends E> list1, final List<? extends E> list2) { 676 return subtract(union(list1, list2), intersection(list1, list2)); 677 } 678 679 /** 680 * Returns a synchronized list backed by the given list. 681 * <p> 682 * You must manually synchronize on the returned list's iterator to 683 * avoid non-deterministic behavior: 684 * </p> 685 * <pre> 686 * List list = ListUtils.synchronizedList(myList); 687 * synchronized (list) { 688 * Iterator i = list.iterator(); 689 * while (i.hasNext()) { 690 * process (i.next()); 691 * } 692 * } 693 * </pre> 694 * <p> 695 * This method is just a wrapper for {@link Collections#synchronizedList(List)}. 696 * </p> 697 * 698 * @param <E> the element type 699 * @param list the list to synchronize, must not be null 700 * @return a synchronized list backed by the given list 701 * @throws NullPointerException if the list is null 702 */ 703 public static <E> List<E> synchronizedList(final List<E> list) { 704 return Collections.synchronizedList(list); 705 } 706 707 /** 708 * Returns a transformed list backed by the given list. 709 * <p> 710 * This method returns a new list (decorating the specified list) that 711 * will transform any new entries added to it. 712 * Existing entries in the specified list will not be transformed. 713 * </p> 714 * <p> 715 * Each object is passed through the transformer as it is added to the 716 * List. It is important not to use the original list after invoking this 717 * method, as it is a backdoor for adding untransformed objects. 718 * </p> 719 * <p> 720 * Existing entries in the specified list will not be transformed. 721 * If you want that behavior, see {@link TransformedList#transformedList}. 722 * </p> 723 * 724 * @param <E> the element type 725 * @param list the list to predicate, must not be null 726 * @param transformer the transformer for the list, must not be null 727 * @return a transformed list backed by the given list 728 * @throws NullPointerException if the List or Transformer is null 729 */ 730 public static <E> List<E> transformedList(final List<E> list, 731 final Transformer<? super E, ? extends E> transformer) { 732 return TransformedList.transformingList(list, transformer); 733 } 734 735 /** 736 * Returns a new list containing the second list appended to the 737 * first list. The {@link List#addAll(Collection)} operation is 738 * used to append the two given lists into a new list. 739 * 740 * @param <E> the element type 741 * @param list1 the first list 742 * @param list2 the second list 743 * @return a new list containing the union of those lists 744 * @throws NullPointerException if either list is null 745 */ 746 public static <E> List<E> union(final List<? extends E> list1, final List<? extends E> list2) { 747 final ArrayList<E> result = new ArrayList<>(list1.size() + list2.size()); 748 result.addAll(list1); 749 result.addAll(list2); 750 return result; 751 } 752 753 /** 754 * Returns an unmodifiable list backed by the given list. 755 * <p> 756 * This method uses the implementation in the decorators subpackage. 757 * </p> 758 * 759 * @param <E> the element type 760 * @param list the list to make unmodifiable, must not be null 761 * @return an unmodifiable list backed by the given list 762 * @throws NullPointerException if the list is null 763 */ 764 public static <E> List<E> unmodifiableList(final List<? extends E> list) { 765 return UnmodifiableList.unmodifiableList(list); 766 } 767 768 /** 769 * Don't allow instances. 770 */ 771 private ListUtils() { 772 // empty 773 } 774 775 }