我很好奇为什么KotlinSet
有索引。您可以使用mySet.elementAt(index)
访问元素。我所知道的其他语言都没有这个特性。如果集合不应该是有序的,但它们有索引,这个特性有用吗?也没有这个特性使Set
芬兰湾的科特林低于其他Set
年代在其他语言吗?
Set
有elementAt
方法,不是因为它是基于索引的(所以它并不比其他语言慢)。只是因为它有这个方法),而是因为它实现了Iterable<T>
。elementAt
是Iterable<T>
的扩展函数:
fun <T> Iterable<T>.elementAt(index: Int): T
Set
是基于什么取决于你使用的Set
的具体实现(Set
只是一个接口)。HashSet
是基于一个哈希表,例如。
所以Set
可以免费获得elementAt
的方法仅仅因为它实现了Iterable<T>
。它不具有elementAt
的唯一方法是不实现Iterable<T>
,但这意味着您不能迭代Set
。这不是很有用,对吧?此外,正如我将在后面讨论的,elementAt
确实有它的用途。
由于elementAt
是Iterable<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
(这是setOf
和mutableSetOf
创建的),那么使用elementAt
是有意义的。
还需要注意,elementAt
确实有O(n)时间,但这并不意味着使用该集合的方法(例如contains
)访问该集合也有O(n)时间。这也取决于您使用的Set
的具体实现。LinkedHashSet.contains
和HashSet.contains
都是O(1) time