为什么Kotlin的Set支持索引访问?该特性是否有用及影响性能?
Kotlin Set 索引能力相关问题解答
为什么无序的Set会支持elementAt(index)方法?
首先要纠正一个常见的认知误区:集合语境下的「Set无序」,指的是不承诺元素顺序稳定、不允许开发者依赖顺序编写业务逻辑,而不是说Set的元素每次遍历都会随机乱序。不同的Set实现本身有自己的顺序规则:比如LinkedHashSet会保留插入顺序,TreeSet会按元素自然排序规则排序,只有最基础的HashSet没有明确的顺序约定,但单次运行过程中的遍历顺序是固定的。elementAt并非Set专属的方法,它是Kotlin给所有Iterable类型统一提供的扩展方法,本质逻辑就是拿到集合的迭代器,遍历到第index位后返回对应元素。Kotlin的集合框架设计逻辑就是尽可能在上层给所有可迭代类型提供统一的通用API,减少开发者针对不同集合类型写重复逻辑的成本,Set作为Iterable的子类型自然就继承了这个方法,不是专门为Set新增的特性。
这个特性有什么实用价值?
- 如果你明确知道当前使用的是有顺序保证的Set实现(比如
LinkedHashSet、TreeSet),可以直接调用方法取对应位置的元素,不需要自己手动实现遍历逻辑,也不需要额外把Set转成List再操作 - 编写通用工具函数时,如果入参定义为
Iterable类型,不管传入的是List、Set还是其他可迭代集合,都可以用统一的API取指定位置元素,不需要做类型判断和转换,代码更简洁 - 调试、打印日志等场景下,可以快速提取Set中的部分元素做查看,不需要额外做类型转换
该特性会不会导致Kotlin的Set性能比其他语言更低?
完全不会,原因如下:
elementAt是扩展方法,不属于Set类本身的成员,你不调用它的话,不会产生任何额外的性能开销,Kotlin的Set底层实现和其他语言对应实现的性能完全一致- 它的默认实现逻辑就是迭代器遍历计数,和你在其他语言里手动写遍历逻辑取Set第n个元素的时间复杂度完全相同,都是O(n),没有额外的性能损耗
- Kotlin只会针对有随机访问能力的集合(比如实现了
RandomAccess接口的List)对elementAt做O(1)的重载优化,不会给Set增加额外的实现负担
内容的提问来源于stack exchange,提问作者Dj Sushi
相关产品推荐
相关产品推荐

