having a hashMap with List as value defined:
private var mMap: HashMap<String, List<DataStatus>>? = null
having a function return a hashMap but with the value of MutableList
fun getDataStatus(response: JSONObject?): HashMap<String, MutableList<DataStatus>> {
return HashMap<String, MutableList<AccountStatusAlert>>()
}
when pass the result to the hashMap expecting List it got error:
mMap = getDataStatus(resp) //<== got error
got error:
Error:(81, 35) Type mismatch: inferred type is HashMap<String,
MutableList<DataStatus>> but HashMap<String, List<DataStatus>>? was expected
You have two solutions depending on your needs.
Cast it
Considering that MutableList
is a subclass of List
, you can cast it. There's only a problem here: you will lose immutability. If you cast the List
back to MutableList
, you can modify its content.
mMap = getDataStatus(repo) as HashMap<String, List<String>>
Convert it
In order to maintain immutability on the list, you have to convert each MutableList
to an immutable List
:
mMap = HashMap<String, List<String>>()
getDataStatus(repo).forEach { (s, list) ->
mMap?.put(s, list.toList())
}
In this case, if you try to modify the content of a list inside mMap
, an exception will be thrown.
If you do not plan to put new items in the map after it was returned to you, just declare your variable having a more permissive type:
// prohibits calling members that take List<DataStatus> as a parameter,
// so you can store a HashMap with values of any List subtype,
// for example of MutableList
private var mMap: HashMap<String, out List<DataStatus>>? = null
or
// prohibits calling mutating methods
// List<DataStatus> already has 'out' variance
private var mMap: Map<String, List<DataStatus>>? = null
If you for some reason need that variable to have exactly that type, then you need to convert or upcast values in the returned map:
mMap = getDataStatus(resp).mapValuesTo(HashMap()) { (_, v) -> v as List<DataStatus> }
One great solution is:
private var mMap: Map<String, List<DataStatus>>? = null // Do you
//really need to have object with interface of HashMap? I don't think so..
mMap = getDataStatus(resp).mapValues { it.value.toList() }
// add as HashMap<String, List<DataStatus>> if you really need
//HashMap interface
So, using var + nullable types is not recommended when using Kotlin. Maybe you want follows:
val mMap = mutableMapOf<String, List<DataStatus>()
or immediately:
val mMap = getDataStatus(resp).mapValues {
it.value.toList()
}