如何高效搜索Person对象列表的所有字段实现全局匹配?
高效搜索Kotlin数据类列表的所有字段匹配方法
针对你需要搜索Person列表中任意字段包含关键词的需求,这里提供两种实用方案,兼顾灵活性和性能:
一、基础反射实现(无需修改原数据类)
如果不想改动Person类结构,可以用Kotlin反射遍历所有String类型属性,判断是否匹配关键词。这种方式适配性强,适合小列表或不频繁搜索的场景。
代码实现
import kotlin.reflect.full.memberProperties // 给List<Person>添加扩展搜索函数 fun List<Person>.searchAllFields(keyword: String): List<Person> { val lowerKeyword = keyword.lowercase() // 统一转小写,实现大小写不敏感匹配 return filter { person -> // 遍历Person的所有属性,检查是否有String值包含关键词 person::class.memberProperties.any { prop -> val fieldValue = prop.get(person) as? String fieldValue?.lowercase()?.contains(lowerKeyword) == true } } } // 使用示例 fun main() { // 修正原代码笔误:telephoneNumer → telephoneNumber val personsList = listOf( Person(name="John", surname="Hams", street="Gariolg", postalCode="929429", telephoneNumber="+2142422422"), Person(name="Karl", surname="Hamsteel", street="Gariolg", postalCode="124215", telephoneNumber="+3526522"), Person(name="Stepf", surname="Hiol", street="Bubmp", postalCode="5342", telephoneNumber="+7574535"), Person(name="Germa", surname="Foo", street="Hutioa", postalCode="235236", telephoneNumber="+112355") ) val result = personsList.searchAllFields("Hams") println(result) // 输出John和Karl的Person对象 }
优缺点
- 优点:无需修改
Person类,新增字段时自动适配,无需改动搜索逻辑 - 缺点:反射性能一般,大列表高频搜索时会有性能损耗
二、预缓存优化方案(高性能推荐)
如果需要处理大列表或高频搜索,建议预缓存每个Person的所有字段内容,避免每次搜索都遍历属性。可以通过数据类内部属性或扩展属性实现。
方式1:修改Person类添加缓存属性
data class Person( val name: String, val surname: String, val street: String, val postalCode: String, val telephoneNumber: String, ) { // 懒加载缓存所有字段的小写拼接内容,仅第一次访问时计算 val searchableContent: String by lazy { listOf(name, surname, street, postalCode, telephoneNumber) .joinToString(separator = " ") .lowercase() } } // 搜索函数 fun List<Person>.searchWithCachedContent(keyword: String): List<Person> { val lowerKeyword = keyword.lowercase() return filter { it.searchableContent.contains(lowerKeyword) } }
方式2:用扩展属性缓存(不修改原Person类)
如果不能改动原Person类,用Kotlin扩展属性实现缓存:
// 给Person添加扩展缓存属性 val Person.searchableContent: String by lazy { listOf(name, surname, street, postalCode, telephoneNumber) .joinToString(separator = " ") .lowercase() } // 搜索函数和方式1一致 fun List<Person>.searchWithCachedContent(keyword: String): List<Person> { val lowerKeyword = keyword.lowercase() return filter { it.searchableContent.contains(lowerKeyword) } }
优缺点
- 优点:预缓存仅计算一次,后续搜索直接匹配字符串,性能远高于反射方案
- 缺点:新增或修改
Person字段时,需要同步更新缓存逻辑中的字段列表
补充说明
- 大小写敏感:如果需要严格区分大小写,去掉代码中
.lowercase()的处理即可 - 空关键词处理:可以在搜索函数开头添加判断,若关键词为空则返回全部列表或空列表,根据需求调整
内容的提问来源于stack exchange,提问作者StuartDTO
相关产品推荐
相关产品推荐

