Mapa de Kotlin: ¿por qué no hay paraHashMap ()?
En Kotlin, la class Map
tiene los methods de extensión toLinkedMap()
y toSortedMap()
.
¿Pero por qué no hay método toHashMap()
? De hecho, la implementación del Map
resultante de muchos methods stdlib es LinkedHashMap
, pero convertirlo a HashMap
en mi código me haría confiar en la implementación que es mala.
- replicar la function de hash de javascript a java / kotlin
- Kotlin smart cast no funciona para LinearLayout.LayoutParams
- Kotlin Coroutines el path correcto en Android
- Kotlin delega con Room persistence lib
- Coincide con los corchetes de la manera kotlin
La introducción de dicho método mantendría a los desarrolladores a salvo de profundizar en la implementación, y con la implementación actual solo realizaría el reparto.
Mi caso de uso es:
val matchesInClass: HashMap<MessageClass, HashMap<Int, Int>> //... for ((cl, matches) in matchesInClass) { matchesInClass[cl] = matches.filterKeys { it !in banned } //error: not a HashMap }
Cuando uso HashMap(matches.filterKeys { it !in banned })
me lleva a la sobrecarga de crear un nuevo map, que me gustaría evitar.
Entonces, ¿es por layout?
- ¿Cuál es el motivo de twitter4j.StreamListner IllegalAccessError en Kotlin?
- Generando jar para proyecto JavaFX en Kotlin
- ¿Cómo probar el método del presentador en base a un valor devuelto por Observable?
- Referencia no resuelta: findViewById en Kotlin
- La testing de instrumento Android con Espresso falla: NoSuchMethodError get () en javax.inject.Provider
- Hacer request HTTP onclick en button en Kotlin
- Cómo convertir un adaptador tipo Gson a un adaptador de tipo Klaxon
- La construcción de Android Studio falló con Kotlin
Estoy de acuerdo en que este lugar en stdlib es inconveniente. Pero, ¿cómo se desea que se implemente una function como toHashMap()
?
La implementación más simple crea un molde as HashMap
si el map subyacente es un HashMap y lo convierte de otra manera. Entonces, el performance de ese código cambiará drásticamente en caso de cambiar la implementación. Eso es malo.
Entonces, en mi humilde opinión, prefiero el lanzamiento inseguro que falla si stdlib
cambia de una manera extraña y me alerta de eso.
De todos modos, siempre puedes informar este problema como un ticket en YouTrack http://youtrack.jetbrains.com/issues/KT . Le dio una buena descripción del problema aquí, así que no debería tomar mucho time.
¿Por qué? es difícil de responder, pero search o agregar un ticket al rastreador de problemas de Kotlin le dará esa respuesta y también le actualizará cuando cambie el estado. Parece que toHashMap
le falta porque toHashSet
está ahí (como de 1.0 BETA 4).
Nota: LinkedHashMap es el valor pnetworkingeterminado porque kotlin desea mantener el order de los elementos a medida que pasa de List
a Set
a List
a Map
a List
y se asegura de que las cosas sigan en su order relativo.
De todos modos, mientras tanto, aquí hay una costumbre en toHashMap
para ti:
public fun <K, V> Iterable<Pair<K, V>>.toHashMap(): Map<K, V> = HashMap<K, V>(collectionSizeOrNull() ?: 16).apply { putAll(this@toHashMap) }
Puede mejorarlo utilizando lógica similar a la function toMap
para elegir el mejor tamaño de map inicial, o no establecerlo y confiar en la implementación de crecimiento pnetworkingeterminada.
Kotlin está construido para ser extendido fácilmente. Si todo se coloca en el stdlib, las personas con dispositivos limitados como Android se quejarán de que es demasiado grande y la mayoría de las cosas que la gente pide son pequeñas rarezas que son algunas líneas de código para poner en su propia lib personalizada.
No es una respuesta a su pregunta original, sino una solución alternativa a su caso de uso.
Aquí está intentando filtrar HashMap<Int, Int>
y asignarlo de nuevo al map del que se tomó:
matchesInClass [cl] = matches.filterKeys {it! in banned} // error: no es un HashMap
Si no tiene el requisito de mantener las matches
HashMap intactas, puede filtrarlas en su lugar invocando la function removeAll
en sus keys
mutable set:
val matchesInClass: HashMap<MessageClass, HashMap<Int, Int>> //... for (matches in matchesInClass.values) { matches.keys.removeAll { it in banned } // notice the inverted condition }
Sería más eficiente que crear una copy filtrada.
Otra alternativa sería usar Map.filterTo
proporcionado con un map vacío del tipo requerido:
for (entry in matchesInClass) { entry.setValue(entry.value.filterTo(HashMap()) { it !in banned }) }
¿Qué tal solo filtrarlo así?
val filtenetworking = matchesInClass.mapValues { it.value.filterKeys { it !in banned } }
- Diferencia de tipo inesperada entre el código equivalente de Java y Kotlin Stream
- Retrofit 2 requestes multipartes