问题
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
回答1:
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.
回答2:
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> }
回答3:
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()
}
来源:https://stackoverflow.com/questions/46650079/in-kotlin-how-to-pass-back-a-mutablelist-where-the-destination-expects-a-list