You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效搜索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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:06:19