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

如何在不重写equals时验证Kotlin集合对象匹配自定义规则

问题:自定义匹配规则下的集合验证方案

我正在开发一个Kotlin函数,需要验证集合中的所有对象在某个特定属性上符合自定义匹配规则。常规做法是用distinctBy()后检查结果大小是否≤1,但现在有个特殊情况:两个不同属性值的对象需要被视为“匹配”,且我不想重写equals方法(因为该逻辑仅适用于此函数)。暴力两两遍历效率不高,求其他实现方案。

参考数据模型

internal enum class IdocsDocumentOwner(val idocsCode: Int, val ownerType: String) {
    Student(2, "Student"),
    Spouse(3, "Student Spouse"),
    Parent1(5, "Father"),
    Parent2(6, "Mother"),
    NonCustodialParent(7, "Noncustodial"),
    Other(8, "Other");
}

当前示例验证函数

fun validateIdocsGroupFiles(owners: List<IdocsDocumentOwner>) {
    
    val distinctOwners = owners.distinctBy { it.idocsCode }
    assert(distinctOwners.count() <= 1)
    // [Student, Student] == true
    // [Student, Parent1] == false
    // [Parent1, Parent2] == true
}

解决方案

1. 自定义分组键(推荐)

给需要“匹配”的对象返回同一个分组键,利用distinctBy()原生的高效去重能力,时间复杂度O(n):

fun validateIdocsGroupFiles(owners: List<IdocsDocumentOwner>) {
    val groupingKey = { owner: IdocsDocumentOwner ->
        when (owner) {
            IdocsDocumentOwner.Parent1, IdocsDocumentOwner.Parent2 -> "PARENT_GROUP"
            else -> owner.idocsCode.toString()
        }
    }
    val distinctGroups = owners.distinctBy(groupingKey)
    check(distinctGroups.size <= 1) { "集合中存在不符合匹配规则的对象" }
}

2. 分组(groupBy)验证

通过groupBy按自定义规则分组,再检查分组数量是否≤1,同样是O(n)复杂度:

fun validateIdocsGroupFiles(owners: List<IdocsDocumentOwner>) {
    val ownerGroups = owners.groupBy { owner ->
        when (owner) {
            IdocsDocumentOwner.Parent1, IdocsDocumentOwner.Parent2 -> "PARENT_GROUP"
            else -> owner.idocsCode
        }
    }
    check(ownerGroups.size <= 1) { "集合中存在不符合匹配规则的对象" }
}

3. 动态匹配检查

先取集合首个元素的匹配范围,再验证所有元素是否都属于该范围,适合规则动态调整的场景:

fun validateIdocsGroupFiles(owners: List<IdocsDocumentOwner>) {
    if (owners.isEmpty()) return
    
    val firstOwner = owners.first()
    val isMatching = { owner: IdocsDocumentOwner ->
        when (firstOwner) {
            IdocsDocumentOwner.Parent1, IdocsDocumentOwner.Parent2 -> 
                owner in setOf(IdocsDocumentOwner.Parent1, IdocsDocumentOwner.Parent2)
            else -> owner.idocsCode == firstOwner.idocsCode
        }
    }
    check(owners.all(isMatching)) { "集合中存在不符合匹配规则的对象" }
}

内容的提问来源于stack exchange,提问作者pbuchheit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:46:19