Why can't I call TreeMap.getOrDefault(key)?



I wrote some code…

val m = HashMap<Int, Int>()
m.getOrDefault(key, 0)

Then later decided I wanted an ordered map, so I changed it to TreeMap. The getOrDefault became an error. Why is that? The method getOrDefault is in java.util.Map.



Kotlin maps the java.util.Map interface to kotlin.Map, which currently contains only the methods from the Map interface declared in JDK 6 (because Kotlin does not currently support specifying the target JDK version). The getOrDefault() method was added in JDK 8, so it’s not present.

To solve this, you can either add an explicit cast to java.util.Map, or use the Kotlin equivalent of the API, which is the withDefault method.


Thanks. But then why did it work with java.util.HashMap?

I keep getting confused by this behavior – the mapping of Java collection types to kotlin.Map, MutableMap, List, etc. I’m sure there is a good reason for it, but I’d like to read the details and rationale. Are they in the docs somewhere? If so, I missed it.



java.util.HashMap is a Java class and not mapped to anything, so Kotlin sees all of its members (other than those inherited from Map and never overridden, which I believe are non-existent).


Okay, I see. The java.util.TreeMap class doesn’t override getOrDefault but java.util.HashMap does.

val m1 = java.util.HashMap<Int, Int>()
val m2 = java.util.TreeMap<Int, Int>()
println(m1.getOrDefault(1, 10))  // ok
println(m2.getOrDefault(1, 10))  // compile error