为什么Kotlin集合有索引?



我很好奇为什么KotlinSet有索引。您可以使用mySet.elementAt(index)访问元素。我所知道的其他语言都没有这个特性。如果集合不应该是有序的,但它们有索引,这个特性有用吗?也没有这个特性使Set芬兰湾的科特林低于其他Set年代在其他语言吗?

SetelementAt方法,不是因为它是基于索引的(所以它并不比其他语言慢)。只是因为它有这个方法),而是因为它实现了Iterable<T>elementAtIterable<T>的扩展函数:

fun <T> Iterable<T>.elementAt(index: Int): T

Set是基于什么取决于你使用的Set的具体实现(Set只是一个接口)。HashSet是基于一个哈希表,例如。

所以Set可以免费获得elementAt的方法仅仅因为它实现了Iterable<T>。它具有elementAt的唯一方法是不实现Iterable<T>,但这意味着您不能迭代Set。这不是很有用,对吧?此外,正如我将在后面讨论的,elementAt确实有它的用途。

由于elementAtIterable<T>的扩展函数,它所能做的就是请求迭代器给它n个元素,并返回最后一个元素。这就是它的实现方式。

public fun <T> Iterable<T>.elementAt(index: Int): T {
if (this is List)
return get(index)
return elementAtOrElse(index) { throw IndexOutOfBoundsException("Collection doesn't contain element at index $index.") }
}
...
public fun <T> Iterable<T>.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T {
if (this is List)
return this.getOrElse(index, defaultValue)
if (index < 0)
return defaultValue(index)
val iterator = iterator()
var count = 0
while (iterator.hasNext()) {
val element = iterator.next()
if (index == count++)
return element
}
return defaultValue(index)
}

如果你的Set没有特定的顺序(例如HashSet),那么它的迭代器也将返回没有特定顺序的元素,所以使用elementAt(x)没有什么意义。另一方面,如果您使用的是有序集合,比如LinkedHashSet(这是setOfmutableSetOf创建的),那么使用elementAt是有意义的。

还需要注意,elementAt确实有O(n)时间,但这并不意味着使用该集合的方法(例如contains)访问该集合也有O(n)时间。这也取决于您使用的Set的具体实现。LinkedHashSet.containsHashSet.contains都是O(1) time

最新更新