Kotlin实现仅保留Google首个元素的列表去重需求
优化方案:单次遍历实现需求并修复异常问题
原代码存在两个核心问题:
- 效率低下:先后对原列表做了三次遍历(两次
filter+一次first),数据量较大时会明显影响性能 - 异常风险:如果列表中没有Google公司的人员,
filter{...}.first()会直接抛出NoSuchElementException,导致程序崩溃
下面是只需要单次遍历的优化实现,同时处理了无Google元素的边界情况:
class Person(val firstName: String, val lastName: String, var age: Int, var isEmployed: Boolean, var companyName: String) { override fun toString(): String = "$firstName $lastName, age:$age, isEmployed: $isEmployed, companyName:$companyName\n" } fun main() { val alist = listOf( Person("Alan", "Walker", 23, true, "Google"), Person("Bee", "dog", 24, true, "Google"), Person("John", "Cena", 25, true, "Google"), Person("See", "S", 26, true, "Stackoverflow"), Person("Soya", "A", 27, true, "Stackoverflow"), Person("Zander", "Cage", 28, true, "Stackoverflow") ) println(alist) val newList = alist.fold(mutableListOf<Person>() to false) { (list, keptGoogle), person -> when { person.companyName == "Google" -> { if (!keptGoogle) { list.add(person) list to true } else { list to true } } else -> { list.add(person) list to keptGoogle } } }.first println(newList) }
实现说明:
- 使用
fold函数单次遍历原列表,同时维护两个状态:结果列表、是否已经保留过Google的第一个元素 - 对每个元素判断:
- 如果是Google员工且还没保留过,就加入结果列表,并标记已保留
- 如果是Google员工但已经保留过,直接跳过
- 非Google员工直接加入结果列表
- 边界情况处理:如果原列表没有Google员工,结果列表会保留所有非Google元素,不会抛出异常
- 额外优化:原代码中用
emptyList()然后+=拼接,改成直接用listOf()初始化不可变列表,更符合Kotlin的最佳实践;toString()用字符串模板简化写法
内容的提问来源于stack exchange,提问作者Candy Crunch
相关产品推荐
相关产品推荐

