【发布时间】:2022-01-12 02:03:35
【问题描述】:
假设我有一个对象列表:
data class Home(
var id: String = "",
var status: MutableMap<String, Double> = mutableMapOf(),
var userName: String = "",
)
var myList = listOf(
Home("1", mutableMapOf("hello", 1.0), "firstUser"),
Home("2", mutableMapOf("hello", 2.0), "secondUser"),
Home("3", mutableMapOf("goodbye", 3.0), "thirdUser")
)
有了这个列表,我想实现一个搜索视图,我想根据地图键或用户名过滤这个列表。例如,如果我搜索“hello”,它将返回一个包含 2 个对象的列表:
listOf(Home("1", mutableMapOf("hello", 1.0), "firstUser"),
Home("2", mutableMapOf("hello", 2.0), "secondUser"))
我正在尝试以下代码但没有成功:
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
myList.stream()
.filter { p ->
p.userName.lowercase(Locale.getDefault())
.contains(newText.lowercase(Locale.getDefault())) ||
p.status.keys.contains(newText.lowercase(Locale.getDefault()))
}
.collect(Collectors.toList())
adapter.submitList(myList)
}
})
请对我做错的地方提出任何建议吗?
编辑:正如@Joffrey 所说,我修改了我的代码,以便可以使用 Kotlin 过滤器。我正在按用户名过滤,没关系。当我尝试通过 map 键过滤 myList 时,我必须插入整个文本才能获得任何结果,例如:“hello”。此时,如果地图的键包含子字符串,我需要过滤列表。
override fun onQueryTextChange(newText: String): Boolean {
val filteredList: List<Home> =
myList.filter {
it.userName.lowercase(Locale.getDefault()).contains(newText.lowercase(Locale.getDefault())) ||
it.status.keys.contains(newText)
}
adapter.submitList(filteredList)
return false
}
【问题讨论】:
-
你通常应该避免在 Kotlin 中使用 Java 流,在 stdlib 中有大量关于集合的函数使得 stream+op+collect 变得多余(你可以直接使用操作)。也就是说,Java 流和 Kotlin 的过滤器都无济于事,因为它们会返回新集合并且不会影响原始集合。基本上,您当前的
onQueryTextChange实现会创建一个新列表,并且不会对它做任何事情。 -
我认为通常您这样做的方式是保留所有数据的原始“完整”列表,然后有一个单独的“过滤”变量,即当前显示的数据。因此,您可以使用
filter的结果重新分配filtered列表,然后以某种方式通知 UI 它需要更新 -
@Joffrey 我刚刚更新了我的代码。使用过滤后的新列表,我更新了回收站视图
-
@Erjon 您仍然没有使用新列表。
myList未修改,流链末尾的collect()调用返回一个新列表。您需要获取此表达式的结果才能获取新列表。如val filteredList = myList.stream().filter{...}.collect(...),或者如我之前所说的使用 Kotlin 的过滤器:val filteredList = myList.filter{...} -
@Joffrey 好的,我按照你说的修改了代码。如果地图包含子字符串,我该如何过滤它?例如,如果我在搜索视图中输入文本“hel”,它应该返回一个包含 2 个对象的过滤列表,因为它会发现列表中有 2 个具有键“hello”的映射。我说清楚了吗?
标签: list kotlin search hashmap searchview