【问题标题】:in kotlin, how to pass back a MutableList where the destination expects a List在 kotlin 中,如何在目标需要 List 的地方传回 MutableList
【发布时间】:2018-03-20 21:03:31
【问题描述】:

拥有一个以 List 作为值定义的 hashMap:

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

有一个函数返回一个 hashMap 但具有 MutableList 的值

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

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

将结果传递给期望 List 的 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

【问题讨论】:

  • 据我所知,您必须将表达式转换为 HashMap&lt;String, List&lt;DataStatus&gt;&gt;

标签: android list inheritance kotlin


【解决方案1】:

根据您的需要,您有两种解决方案。

投射它

考虑到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内的列表内容,将会抛出异常。

【讨论】:

  • @lannyf 感谢您指出了您的疑问,我已经使用更好的解释编辑了我的答案
【解决方案2】:

如果您在返回给您之后不打算将新项目放入地图中,只需声明您的变量具有更宽松的类型:

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

【讨论】:

    【解决方案3】:

    一个很好的解决方案是:

    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
    

    因此,在使用 Kotlin 时不建议使用 var + 可空类型。也许您想要以下内容:

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

    或立即:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多