为什么 Kotlin Sets 有索引?

Why do Kotlin Sets have indices?

我很好奇为什么 Kotlin Set 有索引。您可以使用 mySet.elementAt(index) 访问元素。我所知道的其他语言都没有此功能。如果集合不应该被排序但它们有索引,该功能是否有用?此外,此功能不会使 Kotlin 中的 Sets 比其他语言中的其他 Sets 慢吗?

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

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

Set 基于什么取决于您使用的 Set 的具体实现(Set 只是一个接口)。例如,HashSet 基于散列 table。

所以 Set “免费”得到这个 elementAt 方法只是因为它实现了 Iterable<T>not have elementAt 的唯一方法是不实现 Iterable<T>,但这意味着你不能迭代 Set。这不是很有用,是吗?另外,我稍后会谈到,elementAt 确实有它的用处。

因为 elementAtIterable<T> 上的扩展函数,它真正能做的就是要求迭代器给它 n 个元素,return 最后一个元素。就是这样 implemented.

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),那么它的迭代器将 return 元素也没有特定的顺序,所以使用 elementAt(x)意义不大。另一方面,如果您使用的是有序集,例如 LinkedHashSet(这是 setOfmutableSetOf 创建的),那么使用 elementAt 确实有意义。

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