Kotlin中如何自定义函数作为distinctBy方法的参数?
Kotlin中如何自定义函数传入distinctBy实现灵活去重
问题描述
我有一个存储员工信息的列表,之前用下面的代码通过firstName去重:
val distinctEmployee = employees.distinctBy { it.firstName }
我想自定义一个函数传入distinctBy来实现灵活的列表去重,就像用filter传入自定义函数的方式:
val highSalaryEmployee = employees.filter(salaryFilter) fun salaryFilter(employee: Employee): Boolean { return employee.salary > 350000 }
但我不知道怎么把这个逻辑用到distinctBy上,尝试了下面的代码但有困惑:
val distinctEmployee = employees.distinctBy { firstNameDistinct(it) } fun firstNameDistinct(employee: Employee): Boolean { return employee. // 此处应返回什么? }
请问该如何正确实现?
解决方法
首先要明确distinctBy和filter的参数逻辑差异:
filter接收的是返回Boolean的函数,用来判断元素是否保留;distinctBy接收的是返回任意类型值的函数,这个返回值会作为"去重依据"——只要两个元素的这个返回值相等,就会被视为重复,只保留第一个出现的元素。
所以你不需要让自定义函数返回Boolean,而是返回你用来判断重复的标识值,具体实现如下:
1. 自定义单字段去重函数(比如按firstName)
// 自定义去重依据函数:返回员工的firstName作为去重标识 fun getFirstNameKey(employee: Employee): String { return employee.firstName } // 传入distinctBy使用 val distinctByFirstName = employees.distinctBy { getFirstNameKey(it) } // 或者更简洁的方式,直接传函数引用 val distinctByFirstName = employees.distinctBy(::getFirstNameKey)
2. 自定义多字段组合去重(比如按firstName+lastName)
如果需要更复杂的去重逻辑,比如同时判断姓名全拼是否重复,只需要让函数返回组合后的标识即可:
fun getFullNameKey(employee: Employee): String { return "${employee.firstName}${employee.lastName}" } val distinctByFullName = employees.distinctBy(::getFullNameKey)
3. 自定义任意逻辑的去重依据
甚至可以返回自定义数据类作为标识,只要这个类正确实现了equals和hashCode(Kotlin的数据类默认会实现):
// 定义一个数据类作为去重标识 data class EmployeeKey(val firstName: String, val department: String) fun getEmployeeKey(employee: Employee): EmployeeKey { return EmployeeKey(employee.firstName, employee.department) } // 按"姓名+部门"组合去重 val distinctByDeptAndName = employees.distinctBy(::getEmployeeKey)
总结:distinctBy的核心是提供一个生成"唯一标识"的函数,而不是判断是否保留的条件函数,这是它和filter最本质的区别。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

