Tengo un código como este:
val dm = List[String]()
val dk = List[Map[String,Object]]()
.....
dm.add("text")
dk.add(Map("1" -> "ok"))
pero arroja java.lang.UnsupportedOperationException en tiempo de ejecución.
Necesito declarar una lista vacía o mapas vacíos y en algún lugar más adelante en el código necesito completarlos.
add
operaciónList
?scala.collection.JavaConversions
? Si lo hizo, está viendo la razón por la que recomiendo en suJavaConverters
lugar:dm
ydk
se está convirtiendo en una colección de Java, y luego eladd
método llamado en esa colección. Peor aún,dm
ydk
no se están modificando, incluso si no recibió un error. Y, por cierto, el error es que no1 -> "ok"
esMap[Int,String]
asíMap[String, Object]
.Respuestas:
Las listas de Scala son inmutables por defecto. No puede "agregar" un elemento, pero puede formar una nueva lista agregando el nuevo elemento al frente. Dado que es una lista nueva , debe reasignar la referencia (por lo que no puede usar un val).
var dm = List[String]() var dk = List[Map[String,AnyRef]]() ..... dm = "text" :: dm dk = Map(1 -> "ok") :: dk
El operador
::
crea la nueva lista. También puede utilizar la sintaxis más corta:dm ::= "text" dk ::= Map(1 -> "ok")
NB: En scala no use el tipo
Object
peroAny
,AnyRef
oAnyVal
.fuente
List
es inmutable. Ese es el recomendado para la mayoría de los usos.mutable.List
-List
es un tipo concreto, del cual la única implementación es inmutable. Hay clases inmutables comoLinkedList
yDoubleLinkedList
, que en su mayoría son clases auxiliares. El equivalente de Scala de JavaArrayList
esArrayBuffer
, y el equivalente de JavaLinkedList
esListBuffer
. El rasgo que corresponde a JavaList
esSeq
- del cual haycollection.Seq
y, extendiéndolo,collection.immutable.Seq
ycollection.mutable.Seq
.::=
y+=
?::
está definido, por+=
lo que no funcionará. En otra colección (no en lib estándar): si se implementan::=
o+=
, se usará la implementación. De lo contrario, el compilador se convertiráx::=y
enx = y::x
ex+=y
inrox=x+y
. En el segundo caso, son iguales si la implementación de::
es la misma que la implementación de+
...Si necesita mutar cosas, use
ArrayBuffer
o en suLinkedBuffer
lugar. Sin embargo, sería mejor abordar esta declaración:En lugar de hacer eso, llene la lista con código que devuelva los elementos. Hay muchas formas de hacerlo, y daré algunos ejemplos:
// Fill a list with the results of calls to a method val l = List.fill(50)(scala.util.Random.nextInt) // Fill a list with the results of calls to a method until you get something different val l = Stream.continually(scala.util.Random.nextInt).takeWhile(x => x > 0).toList // Fill a list based on its index val l = List.tabulate(5)(x => x * 2) // Fill a list of 10 elements based on computations made on the previous element val l = List.iterate(1, 10)(x => x * 2) // Fill a list based on computations made on previous element, until you get something val l = Stream.iterate(0)(x => x * 2 + 1).takeWhile(x => x < 1000).toList // Fill list based on input from a file val l = (for (line <- scala.io.Source.fromFile("filename.txt").getLines) yield line.length).toList
fuente
Como ya han mencionado todos, esta no es la mejor forma de usar listas en Scala ...
scala> val list = scala.collection.mutable.MutableList[String]() list: scala.collection.mutable.MutableList[String] = MutableList() scala> list += "hello" res0: list.type = MutableList(hello) scala> list += "world" res1: list.type = MutableList(hello, world) scala> list mkString " " res2: String = hello world
fuente
list ::= "text"
es O (1) que es constante y lo mejor que puede hacer.Como se mencionó en una respuesta anterior , Scala List es una colección inmutable. Puede crear una lista vacía con
.empty[A]
. A continuación, puede utilizar un método:+
,+:
o::
con el fin de añadir elementos a la lista.scala> val strList = List.empty[String] strList: List[String] = List() scala> strList:+ "Text" res3: List[String] = List(Text) scala> val mapList = List.empty[Map[String, Any]] mapList: List[Map[String,Any]] = List() scala> mapList :+ Map("1" -> "ok") res4: List[Map[String,Any]] = List(Map(1 -> ok))
fuente
Por defecto, las colecciones en scala son inmutables, por lo que tiene un método + que devuelve una nueva lista con el elemento agregado. Si realmente necesita algo como un método add, necesita una colección mutable, por ejemplo, http://www.scala-lang.org/api/current/scala/collection/mutable/MutableList.html que tiene un método + =.
fuente
Tal vez pueda usar ListBuffers en scala para crear una lista vacía y agregar cadenas más tarde porque ListBuffers son mutables. Además, todas las funciones de lista están disponibles para ListBuffers en scala.
import scala.collection.mutable.ListBuffer val dm = ListBuffer[String]() dm: scala.collection.mutable.ListBuffer[String] = ListBuffer() dm += "text1" dm += "text2" dm = ListBuffer(text1, text2)
si lo desea, puede convertir esto en una lista usando .toList
fuente
En tu caso utilizo:
val dm = ListBuffer[String]()
yval dk = ListBuffer[Map[String,anyRef]]()
fuente