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