There are two overloads of the method List.remove:
remove(int index) removes an element at the specified index, and
remove(Object element) removes the specified element. When used
with a list of integers (List<Integer>), the overload resolution can be
confusing and may lead to bugs if the wrong overload is selected or if the
code’s intent is not clear to readers.
Consider the following code:
List<Integer> list = new ArrayList<>();
// ...
list.remove(1);
In this case, list.remove(1) calls remove(int index), removing the element
at index 1. If the intention was to remove the element with value 1, this code
is incorrect.
To make the intent explicit and avoid ambiguity, add a comment before the argument:
If you meant to remove by value (element):
list.remove(/* element */ ii);
If you meant to remove by index:
list.remove(/* index */ 1);
If you need to change the type to select the correct overload, you can use explicit boxing/unboxing:
list.remove(Integer.valueOf(i)); // remove by element
list.remove(ii.intValue()); // remove by index
JDK-8384074 discusses adding a
new List::removeAtIndex method to the JDK to avoid this potential overload
confusion.
Suppress false positives by adding the suppression annotation @SuppressWarnings("ListRemoveAmbiguous") to the enclosing element.