Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java List.replaceAll: a thrown operator can leave earlier elements changed

Last updated: 5 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

List.replaceAll applies an operator across elements without promising an all-or-nothing update if that operator throws.

Validate before writing

A batch normalizer may accept the first record and reject a later malformed one. At that point the list can contain both transformed and original values. If the whole queue must change atomically, calculate a separate candidate list, validate every result, then replace the owned reference under the application's publication rule.

The fixture makes the failure deterministic at the second element. It shows the resulting mixed list on the tested LinkedList implementation; callers should rely on the absence of an atomicity promise, not on which prefix an arbitrary implementation will have updated.

Separate element and list ownership

Even a copied list shares element objects unless the elements themselves are copied. This example uses immutable strings, so the candidate values are independent. Shallow copying matters when a replacement operator mutates the contained objects instead.

Working program

Java
import java.util.*;

public class BatchCodeNormalization {
    public static void main(String[] args) {
        LinkedList<String> batchCodes = new LinkedList<String>(Arrays.asList("r-17", "invalid", "r-47"));
        try {
            batchCodes.replaceAll(code -> {
                if (code.equals("invalid")) throw new IllegalArgumentException("bad code");
                return code.toUpperCase(Locale.ROOT);
            });
        } catch (IllegalArgumentException rejected) {
            System.out.println("batch rejected");
        }
        System.out.println(batchCodes);
    }
}

Output

Output
batch rejected
[R-17, invalid, r-47]

Cost and ownership

The scan is O(n) and creates a replacement string for each accepted element. Building a candidate list costs O(n) additional references but allows validation before publication. A mutation of shared element objects needs a deeper ownership policy.

Common Mistakes

  • Do not treat replaceAll as a transaction.
  • Do not publish a partially transformed list after an operator throws.
  • Do not assume copying a list clones its contained objects.

Read next

Java LinkedList: operations, internals and failure cases, Java LinkedList clone: copied nodes, shared element objects, Java collection views: live wrappers, snapshots and shallow copies, Java Iterator and ListIterator: traversal and controlled edits.

java
collections
list-replaceall-partial-failure
Storage details