2017-10-09 103 views
3

具有列表作爲值的散列映射定義:具有一個函數返回一個HashMap但MutableList在科特林,如何傳遞迴一個MutableList其中目標期望列表

 fun getDataStatus(response: JSONObject?): HashMap<String, MutableList<DataStatus>> { 

      return HashMap<String, MutableList<AccountStatusAlert>>() 
    } 
的值

 private var mMap: HashMap<String, List<DataStatus>>? = null 

結果時,傳遞給它遇到錯誤HashMap的期望列表:

 mMap = getDataStatus(resp) //<== got error 

遇到錯誤:

Error:(81, 35) Type mismatch: inferred type is HashMap<String, 
MutableList<DataStatus>> but HashMap<String, List<DataStatus>>? was expected 
+0

據我所知,你必須表達轉換爲'的HashMap <字符串,列表>' –

回答

4

根據您的需要,您有兩種解決方案。

投它

考慮到MutableListList一個子類,你可以施放它。這裏只有一個問題:你將失去永恆性。如果您將List重新設置爲MutableList,則可以修改其內容。

mMap = getDataStatus(repo) as HashMap<String, List<String>> 

將其轉換

爲了保持在名單上不變性,你必須給每個MutableList轉換爲不可變的List

mMap = HashMap<String, List<String>>() 
getDataStatus(repo).forEach { (s, list) -> 
    mMap?.put(s, list.toList()) 
} 

在這種情況下,如果你嘗試修改mMap中的列表內容,將拋出異常。

+0

@lannyf感謝已經指出了你的疑惑,我用一個更好的解釋來編輯我的答案 –

1

如果你不打算把新項目在地圖上它歸還給你後,就宣佈有一個更寬鬆的類型的變量:

// 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 

// prohibits calling mutating methods 
// List<DataStatus> already has 'out' variance 
private var mMap: Map<String, List<DataStatus>>? = null 

如果您由於某種原因需要該變量具有完全相同的類型,則需要在返回的地圖中轉換或上傳值:

mMap = getDataStatus(resp).mapValuesTo(HashMap()) { (_, v) -> v as List<DataStatus> } 
0

一個偉大的解決方案是:

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 

因此,使用VAR +可空類型使用科特林時,不推薦。也許你想如下:

val mMap = mutableMapOf<String, List<DataStatus>() 

或立即:

val mMap = getDataStatus(resp).mapValues { 
it.value.toList() 
}