Hrm, just learning and this is puzzling me: ```val...
# announcements
s
Hrm, just learning and this is puzzling me:
Copy code
val moduleCache : java.util.Map<ModuleInfo, WeakReference<ModuleInfo>> = Collections.synchronizedMap(WeakHashMap<ModuleInfo, WeakReference<ModuleInfo>>())
Copy code
[TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH] Type inference failed. Expected type mismatch: 
required:
java.util.Map<ModuleInfo, WeakReference<ModuleInfo>>
found:
(MutableMap<ModuleInfo!, WeakReference<ModuleInfo>!>..kotlin.collections.Map<ModuleInfo!, WeakReference<ModuleInfo>!>?)
q
Remove java.util from the Map type
s
So if I do that, and look at this full object:
Copy code
object Cache {

    val moduleCache = Collections.synchronizedMap(WeakHashMap<ModuleInfo, WeakReference<ModuleInfo>>())
    val optionCache = Collections.synchronizedMap(WeakHashMap<OptionInfo, WeakReference<OptionInfo>>())

    
    fun <K> intern(map : Map<K, WeakReference<K>>, obj: K) : K {
        val newRef = WeakReference(obj);

        val ref : K? = map.putIfAbsent(obj, newRef)?.get()

        if(ref == null) {
            return obj;
        } else {
            return ref;
        }
    }

    
}
The putIfAbsent method isn't found:
Copy code
[UNRESOLVED_REFERENCE] Unresolved reference: putIfAbsent
What's odd is that with the java.util.Map in there, the following code (that is not generized) does work.
Copy code
fun ModuleInfo.intern() : ModuleInfo {

    val obj = this;

    val newRef = WeakReference(obj);

    val ref : ModuleInfo? = Cache.moduleCache.putIfAbsent(obj, newRef)?.get()

    if(ref == null) {
        return obj;
    } else {
        return ref;
    }
}
Essentially I'm trying to replace that method implementation with:
Copy code
fun ModuleInfo.intern() : ModuleInfo {
 Cache.intern(Cache.moduleCache, this);
}
n
putIfAbsent
isn't found because you have a Map which in Kotlin is immutable (and thus does not have the methods that modify the map). Try to replace
Map
with
MutableMap
s
So I was reading "Kotlin in Action" and maybe it's out of date because it says that "collections in Kotlin are the same classes as in Java" is that something that changed?
Copy code
val moduleCache : java.util.Map<ModuleInfo, WeakReference<ModuleInfo>> = java.util.Collections.synchronizedMap(java.util.WeakHashMap<ModuleInfo, WeakReference<ModuleInfo>>())
If something more recently changed so it's more like Scala with it's own collection classes then I 'half' understand why the above doesn't work, hoewevr even with every class name fully qualified I don't understand where the kotlin type is leaking in from. IntelliJ also seems to think that every method is the Java version.
p
Nothing has changed. Java collection classes are used under the hood, but one typically programs against Kotlin interfaces such as
kotlin.collections.(Mutable)Map
, which only contain a subset of methods present in the Java classes.
s
I guess something is rewriting one of those methods return types, I think Collections.synchronizedMap is not returning the same thing as it would in Java.
p
Why would you think that?
The only magic here is the illusion (offered by kotlinc) that the Java collection classes really implement the Kotlin interfaces.
s
Oh I was trying to understand the simplest example of something weird going on.
Copy code
val map : java.util.Map<String, String> = java.util.HashMap<String, String>()
Kotlin doesn't even let that compile, and I guess IntelliJ gives me a warning, saying that I shouldn't use java.util.Map.
Oh I found the section in the book that talks about it, I'm going to re-read it. It's been a few months and I haven't done anything with it.
Thanks everyone for your help.
p
The compile error looks like a bug (or weird limitation) to me. The warning makes sense in that one should typically use the Kotlin rather than Java collection interfaces.
s
Yeah I'm still just bootstrapping Kotlin in a project and just need to be able to code and slowly absorb the idioms at his point 🙂