Why is this an issue?
When List.remove()
is called it will shrink the list. If this is done inside the ascending loop iterating through all elements it will
skip the element after the removed index.
Noncompliant code example
void removeFrom(List<String> list) {
// expected: iterate over all the elements of the list
for (int i = 0; i < list.size(); i++) {
if (list.get(i).isEmpty()) {
// actual: remaining elements are shifted, so the one immediately following will be skipped
list.remove(i); // Noncompliant
}
}
}
Compliant solution
You can either adjust the loop index to account for the change in the size of the list
static void removeFrom(List<String> list) {
// expected: iterate over all the elements of the list
for (int i = 0; i < list.size(); i++) {
if (list.get(i).isEmpty()) {
// actual: remaining elements are shifted, so the one immediately following will be skipped
list.remove(i);
i--;
}
}
}
Or preferably it’s probably better to rely on Java 8’s removeIf
method
static void removeFrom(List<String> list) {
list.removeIf(String::isEmpty);
}
Exceptions
The descending loop doesn’t have this issue, because the index will be correct when we loop in descending order
void removeFrom(List<String> list) {
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i).isEmpty()) {
list.remove(i);
}
}
}