Как объявить пустой список, а затем добавить строку в scala?

У меня такой код:

val dm  = List[String]()
val dk = List[Map[String,Object]]()

.....

dm.add("text")
dk.add(Map("1" -> "ok"))

но он запускает runtime java.lang.UnsupportedOperationException.

Мне нужно объявить пустой список или пустые карты, а некоторые, где позже в коде нужно их заполнить.

Ответ 1

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, но Any, AnyRef или AnyVal.

Ответ 2

Если вам нужно мутировать вещи, используйте 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

Ответ 3

Как уже упоминалось, это не лучший способ использования списков в 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

Ответ 4

По умолчанию коллекции в scala неизменяемы, поэтому у вас есть метод +, который возвращает новый список с добавленным в него элементом. Если вам действительно нужно что-то вроде метода add, вам нужна изменчивая коллекция, например. http://www.scala-lang.org/api/current/scala/collection/mutable/MutableList.html, который имеет метод + =.

Ответ 5

Возможно, вы можете использовать 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

Ответ 6

В вашем случае я использую: val dm = ListBuffer[String]() и val dk = ListBuffer[Map[String,anyRef]]()