0
votes

I am new in Kotlin. I can't understand why Map DB is not working for me with kotlin. I tried google but it was no help.

gradle

dependencies {
    compile(kotlin("stdlib-jdk8"))
    implementation(group="org.mapdb", name= "mapdb", version= "3.0.7")
    testCompile("junit", "junit", "4.12")
}

File.kt

import org.mapdb.DBMaker

fun main(array: Array<String>) {
    val db = DBMaker.memoryDB().make()
    val map = db.hashMap("map").createOrOpen()
    map.put("a", "a")
    db.close()
}

Error:(7, 13) Kotlin: Type mismatch: inferred type is String but Nothing? was expected. Projected type HTreeMap restricts use of public open fun put(key: K?, value: V?): V? defined in org.mapdb.HTreeMap

Error:(7, 18) Kotlin: Type mismatch: inferred type is String but Nothing? was expected. Projected type HTreeMap restricts use of public open fun put(key: K?, value: V?): V? defined in org.mapdb.HTreeMap

But this works with Java.

public static void main(String[] args) {
        DB db = DBMaker.fileDB("java.db").fileMmapEnable().transactionEnable().make();
        ConcurrentMap map = db.hashMap("map").createOrOpen();
        map.put("a", "b");
        map.put("a2", "b");
        System.out.println(map);
        System.out.println(map.getClass());
        db.commit();
        db.close();

        DB db2 = DBMaker.fileDB("java.db").fileMmapEnable().transactionEnable().make();
        ConcurrentMap map2 = db2.hashMap("map").open();

        System.out.println(map2);
        map2.forEach((o, o2) -> {
            System.out.println(o+" = "+o2);
        });
    }
1
I haven't used this library or tried your code, but from the error messages I'd guess this is about the type parameters of the map. Java allows 'raw' types, where you don't have to specify the type parameters and anything is allowed, but Kotlin doesn't. It looks like Kotlin can't tell what the key or value types of the map are, and so complains when you try to put() a String-to-String mapping. I'd try casting the map to MutableMap<String, String>.gidds
Just to be clear, using raw types is bad in Java as well, they exist primarily to allow truly ancient pre-generics code to compile without changes.Alexey Romanov

1 Answers

1
votes

@gidds is completely right about that Kotlin doesn't allow "raw" Java types and requires type parameters. So you can just cast your map like this and it will work fine.

fun main(array: Array<String>) {
    val db = DBMaker.memoryDB().make()
    val map = db.hashMap("map").createOrOpen() as MutableMap<String, String>
    map.put("a", "a")
    db.close()
}

If you don't like unchecked casts as I do, you can use a bit more verbose HashMapMaker constructor like this.

fun main(array: Array<String>) {
    val db = DBMaker.memoryDB().make()
    val map = DB.HashMapMaker<String, String>(db, "map").createOrOpen()
    map["a"] = "a"
    db.close()
}