Inappropriate Collection Call

ID

java.inappropriate_collection_calls

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

best-practice, reliability

Description

Reports a call to Collection.remove(Object), Collection.contains(Object), Collection.removeAll(Collection), List.indexOf(Object) or List.lastIndexOf(Object) whose argument’s declared type is unrelated to the collection’s own declared element type.

Map.containsKey/containsValue/get/getOrDefault/remove are a known limitation and are never reported: the API used to read a collection’s element type collapses a `Map’s key/value pair to no element type at all, so the key and value types cannot be told apart.

Rationale

Every one of these methods takes a bare Object argument and compares it against the elements already in the collection. If the argument’s type cannot possibly be one of those elements — because neither type is a subtype of the other — the comparison is not occasionally wrong, it is always wrong: contains/indexOf/lastIndexOf always return false/-1, remove/ removeAll always leave the collection untouched. The branch guarded by the result never runs, and the removal that looked intentional never happens.

void purge(List<String> tags, Integer legacyId) {
  tags.remove(legacyId); // always returns false: no String in tags equals an Integer
}

Remediation

Convert the argument to the collection’s element type before the call, or fix the collection’s declared type if the argument’s type was the one that was actually intended:

void purge(List<String> tags, Integer legacyId) {
  tags.remove(String.valueOf(legacyId)); // compares like with like
}

© 2026 Xygeni. All rights reserved