未经检查的 Cast 警告和 ClassCastException

Unchecked Cast warnning and ClassCastException

我在 publishResults 方法中有以下代码,其中包含适配器 class 实现 Filterable 接口来过滤项目列表。 (objective:使用搜索视图过滤回收站视图中的项目)

override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
  // taskList is of type MutableList<TaskItem>  
  taskList.clear()

  // crash on
  taskList.addAll(results!!.values as Collection<TaskItem>)

  notifyDataSetChanged()
}

点击搜索图标时应用崩溃并出现以下错误

java.lang.ClassCastException: android.widget.Filter$FilterResults cannot be cast to java.util.Collection

AS 还显示以下警告

Unchecked cast: Any! to Collection<TaskItem>

如何在不强制转换的情况下将任务列表转换为集合?


更新:

按照@Andrei 的要求添加了performFiltering 方法

override fun performFiltering(constraint: CharSequence?): FilterResults {

            val filteredList = ArrayList<TaskItem>()

            if(constraint == null || constraint.isEmpty()){
                filteredList.addAll(duplicatedTaskList)
            }
            else{
                val filterPattern: String = constraint.toString().toLowerCase().trim()

                for (taskItem in duplicatedTaskList){
                    if(taskItem.title.toLowerCase().contains(filterPattern))
                        filteredList.addAll(duplicatedTaskList)

                }
            }
            val filterResults = FilterResults()
            filterResults.values = filterResults

            return filterResults
        }

我会在 results!!.values 上循环并使用 for 循环检查该项目是否为 TaskItem。 做这个 if 语句比使用 as (casting) 更安全,因为它会导致未经检查的转换错误。

for (item in results!!.values) { 
  if(item is TaskItem) {
    taskList.add(item)
  } else {
      // Item is not task item, handle it 
  }
}

编辑

for (i in 0 until results!!.values.size) { 
  if(results!!.values.get(i) is TaskItem) {
    taskList.add(item)
  } else {
      // Item is not task item, handle it 
  }
}

也尝试使用:

filterResults.values = filteredList

在你的performFiltering方法中应该是

filterResults.values = filteredList

而不是

filterResults.values = filterResults

那么你的转换代码就可以工作了

如果 results 为 null,

使用 results!!.values as Collection<TaskItem> 会给您一个异常,请考虑改用可空性运算符 (results?.values)。

也许可以试试这样的方法:

val list = results?.values as? Collection<*>

list?.let{
//here, you can use `it` to check if your list is not null
}

我使用的一个简单的解决方案(虽然我不知道是否推荐) 是在 performFiltering()publishResults() 方法中使用相同的列表。

 taskList.addAll(filteredList); 
//Define filteredList outside as global variable

我看不出有任何理由首先在 performFiltering() 方法中将项目添加到 filteredList,然后将 filteredResults.value 设置到同一个列表,然后在 publishResults() 方法中试图取回相同的列表。定义全局变量列表似乎是更好的选择。