Replacing Elements in Collections

Both the List<E> interface and the Collections class define a replaceAll() method to replace elements in a collection, but they operate differently.

Click here to view code image

// Defined in the List<E> interface.
void replaceAll(UnaryOperator<E> operator)

With this method, each element is replaced with the result of applying the specified operator to that element of this list. Unary operators are covered in §13.10, p. 720.

Click here to view code image

// Defined in the Collections class.
<E> boolean replaceAll(List<E> list, E oldVal, E newVal) // Collections

Replaces all elements equal to oldVal with newVal in the list; it returns true if the list was modified.

The following code snippet illustrates how the replaceAll() method of the List<E> interface can be used to apply a UnaryOperator to each element of the list. The lambda expression at (1a) is executed for each string in the list strList, replacing each element with an uppercase version of the string. Equivalent method reference is used for the same purpose at (1b).

Click here to view code image

// Before: [biggest, big, bigger, Bigfoot]
strList.replaceAll(str -> str.toUpperCase());      // (1a)
strList.replaceAll(String::toUpperCase);           // (1b)
// After: [BIGGEST, BIG, BIGGER, BIGFOOT]

In contrast, the replaceAll() method of the Collections class can be used to replace all occurrences of a specific value in the collection with a new value. In the list palindromes of strings, the occurrence of the string “road” is replaced by the string “anna” in the method call below.

Click here to view code image

// Before: [eye, level, radar, road]
Collections.replaceAll(palindromes, “road”, “anna”);
// After: [eye, level, radar, anna]

The majority of the methods found in the Collections class that replace the elements of a collection operate on a List, while one method operates on arbitrary Collections. They all change the contents of the collection in some way.

Click here to view code image

<E> boolean addAll(Collection<? super E> collection, E… elements)

Adds the specified elements to the specified collection. This is a convenient method for loading a collection with individually specified elements or an array. The method is annotated with @SafeVarargs because of the variable arity parameter. The annotation suppresses the heap pollution warning in its declaration and the unchecked generic array creation warning at the call sites.

Click here to view code image

<E> void copy(List<? super E> destination, List<? extends E> source)

Adds the elements from the source list to the destination list. Elements copied to the destination list will have the same index as in the source list. The destination list cannot be shorter than the source list. If it is longer, the remaining elements in the destination list are unaffected.

Click here to view code image

<E> void fill(List<? super E> list, E element)

Replaces all of the elements of the list with the specified element.

Click here to view code image

<E> List<E> nCopies(int n, E element)

Creates an immutable list with n copies of the specified element. The same reference value of the specified element is saved in the list for all references.

The addAll() method is a convenient method for loading an existing collection with a few individually specified elements or an array of small size. Several examples of its usage can be found in this chapter. The array passed should be an array of objects. Note also the autoboxing of the int values specified at (1) and (2). The addAll() method does not allow primitive arrays as a variable arity argument, as attempted at (3).

Click here to view code image

List<Integer> intList = new ArrayList<>();            // []
Collections.addAll(intList, 9, 1, 1);                 // (1) Varargs
// After: [9, 1, 1]
Collections.addAll(intList, new Integer[] {1, 1, 9}); // (2) An array of Integers
// After: [9, 1, 1, 1, 1, 9]
Collections.addAll(intList, new int[] {1, 9, 1});     // (3) Compile-time error!

As we can see at (2), the collection returned by the Collections.addAll() method is not of fixed size as more elements can be added to it. This is in contrast to the list returned by the Array.asList() method (§12.7, p. 659). However, the addAll() method of the Collection<E> interface can be used for adding an arbitrary collection to an existing collection.

When using the Collections.copy() method to copy elements from the source list to the destination list, the elements are copied to the same positional index in the destination list as they were in the source list.

Click here to view code image

List<String> dest = new ArrayList<>();
Collections.addAll(dest, “one”, “two”, “three”, “four”);// [one, two, three, four]
List<String> src = new ArrayList<>();
Collections.addAll(src, “I”, “II”, “III”);              // [I, II, III]
Collections.copy(dest, src);                            // [I, II, III, four]

All elements of a list can be replaced with the same element, as shown at (1):

Click here to view code image

List<String> strList = new ArrayList<>();
Collections.addAll(strList, “liberty”, “equality”, “fraternity”);
// Before: [liberty, equality, fraternity]
Collections.fill(strList, “CENSORED”);                  // (1)
// After: [CENSORED, CENSORED, CENSORED]

Earlier we saw usage of the Collections.nCopies() method in Example 15.10 and Example 15.11. The for(;;) loop below

Click here to view code image

for (int i = 0; i < 5; ++i)
  System.out.printf(“%d %s%n”, i, Collections.nCopies(i, “*”));

prints the following:

0 []
1 [*]
2 [*, *]
3 [*, *, *]
4 [*, *, *, *]

Leave a Reply

Your email address will not be published. Required fields are marked *