¿Hay alguna manera de build un HashSet con function de initialization en Kotlin?

Para leer las estrellas de un file en el problema de constelaciones Boomerang 2016 de Facebook Hacker Cup , se puede definir la siguiente function de extensión:

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

El código es compacto, pero los valores se leen primero en una matriz y luego se convierten en un HashSet . ¿Hay alguna manera de inicializar directamente un HashSet con el tamaño de n y la function de initialization en Kotlin?

ACTUALIZACIÓN: ¿Hay una forma existente en las librerías estándar de Kotlin?

Siempre puede usar apply para inicializar objects en el lugar:

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

Si eso también es demasiado inconveniente, escriba cada vez, escriba una function de extensión:

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

Uso:

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

Debido a que HashSet es una class Java, solo puede inicializarlo de la forma indicada por JDK.

Si bien no hay un método de ayuda en el time de ejecución de Kotlin , es fácil escribirlo usted mismo así:

 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 } 

Como @miensol ha señalado, la initialization de HashSet está limitada a los constructores puestos a disposition por el JDK. Kotlin ha agregado una function hashSetOf que inicializa un HashSet vacío y luego le agrega los elementos especificados.

Para evitar la primera lectura de los valores en una matriz, puede usar un kotlin.Sequence los "valores evaluados perezosamente":

 fun BuffenetworkingReader.readStars(n: Int): Set<Star> { return lineSequence().take(n).map { val (l1, l2) = it.split(" ").map { it.toInt() } Star(l1, l2) }.toHashSet() } 

Parece que estás haciendo una pregunta XY ( http://xyproblem.info/ ). Realmente desea saber cómo escribir readStars de la manera más eficiente, pero en su lugar pregunta acerca de HashSet . Creo que @ mfulton26 también responde su pregunta dependiendo de lo que se le pregunte.

Aquí está la respuesta para "cómo escribo esto de la manera más eficiente":

Tienes dos opciones. Primero, una versión que cierra automáticamente la secuencia al final:

 fun BuffenetworkingReader.readStars(n: Int): Set<Star> { return use { lineSequence().map { line -> val idx = line.indexOf(' ') Star(line.substring(0, idx).toInt(), line.substring(idx + 1).toInt()) }.toSet() } } 

Y segundo, una versión que no:

 fun BuffenetworkingReader.readStars(n: Int): Set<Star> { return lineSequence().map { line -> val idx = line.indexOf(' ') Star(line.substring(0, idx).toInt(), line.substring(idx+1).toInt()) }.toSet() } 

Ninguna versión crea una matriz, ni hacen copys de datos. Transmiten los datos a través de una secuencia que crea el set y lo llena directamente.

Otras notas

No es necesario utilizar split si realmente está preocupado por las asignaciones y el performance. Solo use indexOf(char) y divida la cadena usted mismo usando substring .

Si haces una split, entonces usa split(char) not split(String) cuando estás buscando dividir en un char

  • Maneras de ofuscar el acceso a miembros de la class preferentemente privados, pero en realidad públicos, con el fin de utilizarlos en methods en línea
  • Referencia no resuelta de la function de secuencia de Kotlin
  • ¿Por qué no puedo usar la interfaz como el tipo genérico en este transformador Rx?
  • Error al ejecutar la testing: la ejecución de la instrumentación falló debido a 'kotlin.UninitializedPropertyAccessException'
  • ¿Cómo soluciono el error de inferencia de tipo en un Completable transformado utilizando RxLifecycle.bindToLifecycle ()?
  • Kotlin: método genérico y para bucle preguntando por iterador ()
  • NoClassDefFoundError en la class Kotlin en la testing JUnit en time de ejecución
  • ¿Por qué este ChildEventListener no está leyendo datos del nodo firebase?
  • ¿Cómo puedo get un número aleatorio en Kotlin?
  • Kotlin coroutines CalledFromWrongThreadException
  • Rect-Kotlin wrapper setState método