Traditional for or foreach loops that filter elements, transform them, or collect results into a collection can be more clearly expressed using functional collection processing APIs that provide declarative iteration constructs.
Modern programming languages provide declarative, functional interfaces for processing collections. Traditional imperative loops that perform filtering, mapping, or collecting operations can be harder to read and understand at a glance because:
Common patterns that benefit from declarative collection processing include:
Declarative collection processing expresses these operations more clearly by:
filter, map, and collectWhile the traditional loop and declarative version are functionally equivalent, the declarative version communicates intent more directly, making the code easier to maintain and understand.
In Java, this declarative approach was introduced in Java 8 through the Stream API.
This issue affects code maintainability and readability. While it doesn’t introduce bugs or security vulnerabilities, converting imperative iteration constructs to modern functional collection processing APIs:
The impact is primarily on developer productivity - code that clearly expresses intent is faster to understand, review, and modify.
Replace the traditional loop with a stream pipeline. Start with collection.stream(), then chain the appropriate intermediate
operations (filter, map), and finish with a terminal operation (collect, findFirst, etc.).
List<String> result = new ArrayList<>();
for (Item item : items) {
if (item.isActive()) { // Noncompliant
result.add(item.getName());
}
}
List<String> result = items.stream()
.filter(Item::isActive)
.map(Item::getName)
.collect(Collectors.toList());