未经检查的 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()
方法中试图取回相同的列表。定义全局变量列表似乎是更好的选择。
我在 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()
方法中试图取回相同的列表。定义全局变量列表似乎是更好的选择。