Kotlin如何按Map键子串或用户名实现对象列表过滤功能
问题排查与修复方案
初始代码的核心问题
- 过滤结果未接收使用:Java Stream 过滤后通过
collect生成的新列表没有赋值给变量,你直接将原始未过滤的myList提交给了适配器,所以界面永远展示全量数据,不会出现过滤效果。 - 匹配逻辑不符合需求:
p.status.keys.contains(xxx)是判断Map中是否存在完全等于搜索词的键,而非判断键是否包含搜索子串,和要求的匹配规则不符。 - 语法适配问题:Kotlin 原生提供了更简洁的集合操作API,不需要额外使用Java Stream,编码效率和运行性能都更优。
子串匹配逻辑修改方案
你修改后的代码问题仍然出在Map键的匹配逻辑上:it.status.keys.contains(newText)还是完全匹配键的逻辑,且没有统一大小写处理。只需将这部分替换为any()函数判断「是否存在任意一个键包含搜索子串」即可,完整实现如下:
override fun onQueryTextChange(newText: String): Boolean { // 提前将搜索词统一转小写,避免重复计算 val queryKeyword = newText.lowercase(Locale.getDefault()) val filteredList: List<Home> = myList.filter { homeItem -> // 规则1:用户名包含搜索子串(大小写不敏感) homeItem.userName.lowercase(Locale.getDefault()).contains(queryKeyword) // 规则2:status中任意一个键包含搜索子串(大小写不敏感) || homeItem.status.keys.any { statusKey -> statusKey.lowercase(Locale.getDefault()).contains(queryKeyword) } } adapter.submitList(filteredList) return false }
逻辑说明
any()是Kotlin集合的内置函数,遍历集合时只要有一个元素满足判断条件就会返回true,正好匹配「只要status的键有一个包含搜索子串就算命中」的需求。同时提前统一转换搜索词的大小写,避免循环中重复转换,也保证了大小写不敏感的匹配效果。
内容的提问来源于stack exchange,提问作者Erjon
相关产品推荐
相关产品推荐

