The Kotlin collections API has methods that allow developers to overcome type-safety restriction of the parameter, such as
Iterable.contains. When the actual type of the object provided to these methods is not consistent with the target collection’s actual
type, those methods will always return false or null. This is most likely unintended and hides a design problem.
This rule raises an issue when the type of the argument of the following APIs is unrelated to the type used for the collection declaration:
-
MutableCollection.remove
-
MutableCollection.removeAll
-
MutableCollection.retainAll
-
Array.contains
-
Array.indexOf
-
Array.lastIndexOf
-
Collection.containsAll
-
Iterable.contains
-
Iterable.indexOf
-
Iterable.lastIndexOf
-
List.indexOf
-
List.lastIndexOf
-
Map.contains
-
Map.containsKey
-
Map.containsValue
-
Map.get
-
MutableMap.remove
Noncompliant code example
fun main(args: Array<String>) {
val map: MutableMap<Int, Any> = mutableMapOf()
map.remove<Any, Any>("42") // Noncompliant; will return 'null' for sure because 'map' is handling only Integer keys
// ...
val list: MutableList<String> = mutableListOf()
val integer = Integer.valueOf(1)
if (list.contains<Any>(integer)) { // Noncompliant; always false.
list.remove<Any>(integer) // Noncompliant; list.add(integer) doesn't compile, so this will always return 'false'
}
}
Compliant solution
fun main(args: Array<String>) {
val map: MutableMap<Int, Any> = mutableMapOf()
map.remove(42)
// ...
val list: MutableList<String> = mutableListOf()
val str = ""
if (list.contains(str)) {
list.remove(str)
}
}