Philipp Claßen Philipp Claßen - 23 days ago 7
Java Question

Does java.util.HashMap not implement java.util.Map in Kotlin?

I have trouble understanding why a Java

HashMap
is incompatible with a Java
Map
in Kotlin:

val map : java.util.Map<Int, Int> = java.util.HashMap<Int, Int>()
// ERROR: Type mismatch


Is this a bug or is it intentionally enforced to be an error in Kotlin?




Here is a second example with the Java to Kotlin compiler. Take a look at this Java example file:

public class Test {
public static void main(String[] args) {
java.util.Map<Integer, Integer> map = new java.util.HashMap<>();
insertValue(map);
}

private static void insertValue(java.util.Map<Integer, Integer> map) {
map.putIfAbsent(0, 1);
}
}


Running "Convert Java to Kotlin" results in this file:

object Test {
@JvmStatic fun main(args: Array<String>) {
val map = java.util.HashMap<Int, Int>()
insertValue(map)
}

private fun insertValue(map: Map<Int, Int>) {
map.putIfAbsent(0, 1) // ERROR! Unresolved reference
}
}


If I try to modify it to reflect more the original file, where
insertValue
expected a Java
java.util.Map
, I get another error:

object Test {
@JvmStatic fun main(args: Array<String>) {
val map = java.util.HashMap<Int, Int>()
insertValue(map) // ERROR: Type mismatch
}

private fun insertValue(map: java.util.Map<Int, Int>) {
map.putIfAbsent(0, 1) // is now OK
}
}

Answer

In Kotlin, a java.util.HashMap, at compile time, does not implement java.util.Map, but implements kotlin.collections.MutableMap which extends the read-only kotlin.collections.Map.

This is because of Kotlin's mapped types. See Collections in Kotlin M3 is Out! for more details.

MutableMap does not define any putIfAbsent, but it has an extension function getOrPut.

Comments