有没有办法在Kotlin中用initializator函数构造HashSet?

Vil*_*kas 5 kotlin

要阅读Facebook Hacker Cup 2016 Boomerang Constelations问题中的文件星标,可以定义以下扩展功能:

fun BufferedReader.readStars(n: Int): Set<Star> {
    return Array(n) {
        val (l1, l2) = readLine().split(" ").map { it.toInt() }
        Star(l1, l2)
    }.toHashSet()
}
Run Code Online (Sandbox Code Playgroud)

代码很紧凑,但首先将值读入数组,然后转换为a HashSet.有没有办法在Kotlin中直接初始化a 和sizeizator函数HashSet的大小n

更新:标准Kotlin库中是否存在现有方法?

Kir*_*man 7

您始终可以使用它apply来就地初始化对象:

HashSet<Star>(n).apply {
    repeat(n) {
        val (l1, l2) = readLine()!!.split(' ').map { it.toInt() }
        put(Star(l1, l2))
    }
}
Run Code Online (Sandbox Code Playgroud)

如果每次都太不方便,请写一个扩展功能:

inline fun <T> createHashSet(n : Int, crossinline fn: (Int) -> T) = HashSet<T>(n).apply {
    repeat(n) { add(fn(it)) }
}
Run Code Online (Sandbox Code Playgroud)

用法:

createHashSet<Star>(n) {
    val (l1, l2) = readLine()!!.split(' ').map { it.toInt() }
    Star(l1, l2)
}
Run Code Online (Sandbox Code Playgroud)


mie*_*sol 5

因为HashSet是一个java类所以你只能用JDK提供的方式初始化它.

虽然在Kotlin运行时没有辅助方法,但是很容易自己编写它:

public fun <T> hashSetOf(size: Int, initializer: (Int) -> T): HashSet<T> {
    val result = HashSet<T>(size)
    0.rangeTo(size - 1).forEach {
        result.add(initializer(it))
    }
    return result
}
Run Code Online (Sandbox Code Playgroud)