У меня такой код:
val dm = List[String]()
val dk = List[Map[String,Object]]()
.....
dm.add("text")
dk.add(Map("1" -> "ok"))
но он выдает исключение java.lang.UnsupportedOperationException во время выполнения.
Мне нужно объявить пустой список или пустые карты и кое-где позже в коде нужно их заполнить.
add
операцияList
?scala.collection.JavaConversions
? Если да, то вы видите именно ту причину, по которой я рекомендуюJavaConverters
вместо этого:dm
иdk
преобразуются в коллекцию Java, а затемadd
метод вызывается для этой коллекции. Хуже того ,dm
иdk
не модифицируются, даже если вы не получите сообщение об ошибке. И, кстати, ошибка в том , что1 -> "ok"
этоMap[Int,String]
неMap[String, Object]
.Ответы:
Списки Scala по умолчанию неизменяемы. Вы не можете «добавить» элемент, но вы можете сформировать новый список, добавив новый элемент впереди. Поскольку это новый список, вам нужно переназначить ссылку (чтобы вы не могли использовать val).
var dm = List[String]() var dk = List[Map[String,AnyRef]]() ..... dm = "text" :: dm dk = Map(1 -> "ok") :: dk
Оператор
::
создает новый список. Вы также можете использовать более короткий синтаксис:dm ::= "text" dk ::= Map(1 -> "ok")
NB: В scala не используйте тип
Object
butAny
,AnyRef
илиAnyVal
.источник
List
неизменен. Это рекомендуемый вариант для большинства случаев использования.mutable.List
-List
это конкретный тип, единственная реализация которого неизменна. Существуют неизменяемые классы, такие какLinkedList
иDoubleLinkedList
, которые в основном являются вспомогательными. Scala эквивалент в JavaArrayList
являетсяArrayBuffer
, и эквивалент в JavaLinkedList
естьListBuffer
. Черта , которая соответствует в JavaList
естьSeq
- из которых естьcollection.Seq
и, расширяя его,collection.immutable.Seq
иcollection.mutable.Seq
.::=
и+=
?::
определяется, так+=
что работать не будет. В другой коллекции (не в стандартной библиотеке): если реализованы::=
или+=
, будет использоваться реализация. В противном случае, компилятор превратитсяx::=y
вx = y::x
иx+=y
Инроx=x+y
. Во втором случае они такие же, если реализация::
совпадает с реализацией+
...Если вам нужно мутировать вещи, использование
ArrayBuffer
илиLinkedBuffer
вместо этого. Однако было бы лучше обратиться к этому заявлению:Вместо этого заполните список кодом, который возвращает элементы. Есть много способов сделать это, и я приведу несколько примеров:
// 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
источник
Как уже было сказано, это не лучший способ использования списков в 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
источник
list ::= "text"
выглядит следующим образом: O (1) является постоянным и лучшим, что вы можете сделать.Как упоминалось в ответе выше , список Scala является неизменной коллекцией. Вы можете создать пустой список с помощью
.empty[A]
. После этого вы можете использовать метод:+
,+:
или::
для того , чтобы добавить элемент в список.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))
источник
Коллекции по умолчанию в scala неизменяемы, поэтому у вас есть метод +, который возвращает новый список с добавленным к нему элементом. Если вам действительно нужно что-то вроде метода добавления, вам нужна изменяемая коллекция, например http://www.scala-lang.org/api/current/scala/collection/mutable/MutableList.html, у которой есть метод + =.
источник
Возможно, вы можете использовать ListBuffers в scala для создания пустого списка и добавления строк позже, потому что ListBuffers изменяемы. Также все функции List доступны для ListBuffers в 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)
если вы хотите, вы можете преобразовать это в список с помощью .toList
источник
В вашем случае я использую:
val dm = ListBuffer[String]()
иval dk = ListBuffer[Map[String,anyRef]]()
источник