Kotlin中如何高效从对象列表提取指定属性生成新列表?
问题
假设存在Person类,包含name和age两个属性,现有存储了n个Person实例的列表persons。除了如下实现方式外,是否有更高效的方案从persons列表中提取所有age属性生成年龄列表?
原实现代码:
val age_list= ArrayList<Int>() for(person in persons){ age_list.add(person.getAge()) }
回答
首先明确:你手写的循环时间复杂度已经是O(n),属于理论最优的时间复杂度,不存在时间效率更高的方案,我们能优化的是代码简洁度、空间效率以及避免不必要的性能损耗。
1. 标准库内置map方法(最推荐)
Kotlin集合的标准库已经封装了这类属性提取的操作,直接调用map方法即可,代码更简洁,性能和你手写的循环相当甚至更好:
// 如果age是Kotlin属性直接调用 val ageList = persons.map { it.age } // 如果是Java风格getter就用getAge() val ageList = persons.map { it.getAge() }
这个方法的内部实现就是预先创建了和原列表大小完全一致的容器,遍历填充后返回只读列表,不会出现你手动初始化ArrayList时默认容量不足导致的扩容开销,空间效率更高。
2. 如果你需要可变的ArrayList
可以用mapTo方法直接把结果写入你指定的ArrayList,不需要额外的类型转换:
val ageList = persons.mapTo(ArrayList(persons.size)) { it.getAge() }
这个实现和你手写的循环逻辑完全一致,性能没有任何差异,只是写法更简洁。
注意事项
如果你的列表量级特别大(百万级以上),不要额外转成Sequence处理,Sequence的惰性求值特性在这种简单的全量映射场景下反而会带来额外的性能开销,直接用上述的map方法或者你原来的循环即可。
内容的提问来源于stack exchange,提问作者Orl13
相关产品推荐
相关产品推荐

