This rule raises an issue when a loop iterates over a list and replaces each element with a transformed version of itself, instead of using a dedicated list transformation method designed for in-place element replacement.

In Java, this dedicated method is List.replaceAll(), which has been available since Java 8.

Why is this an issue?

Traditional loops that iterate over a list to replace each element with a transformed version are a common pattern in older codebases. While functionally correct, this approach has several drawbacks:

Verbosity: Index-based loops require explicit index management, bounds checking, and manual calls to retrieve and update elements at each position. This adds boilerplate code that obscures the actual intent.

Readability: The loop structure forces readers to mentally parse the iteration mechanics before understanding the transformation logic. The real purpose - applying a function to each element - is hidden within the loop body.

Error-prone: Manual index management introduces opportunities for off-by-one errors or incorrect loop bounds. Even though these are typically caught quickly, they add unnecessary risk.

Modern languages provide dedicated methods for in-place list transformation that address this pattern. These methods:

These transformation methods accept a function that takes an element and returns a transformed element of the same type. This functional approach aligns with modern programming idioms and makes the code more declarative: you specify what transformation to apply rather than how to iterate and apply it.

In Java, the List.replaceAll(UnaryOperator<E> operator) method was introduced in Java 8 to address this pattern. The method takes a UnaryOperator - a functional interface representing a function that accepts and returns the same type.

What is the potential impact?

Using traditional loops instead of declarative collection transformation methods does not introduce bugs or security vulnerabilities. However, it does impact code maintainability:

In Java, this specifically refers to methods like List.replaceAll() for transforming list elements in place.

How to fix it

Replace the loop with a call to List.replaceAll(). Pass a UnaryOperator that performs the transformation. You can use a lambda expression or a method reference depending on the complexity of the transformation.

Code examples

Noncompliant code example

for (int i = 0; i < list.size(); i++) {
    list.set(i, list.get(i).toUpperCase()); // Noncompliant
}

Compliant solution

list.replaceAll(String::toUpperCase);

Resources

Documentation