Mam taki kod:
val dm = List[String]()
val dk = List[Map[String,Object]]()
.....
dm.add("text")
dk.add(Map("1" -> "ok"))
ale generuje java.lang.UnsupportedOperationException środowiska wykonawczego.
Muszę zadeklarować pustą listę lub puste mapy, a niektóre miejsca w kodzie muszą je wypełnić.
add
operacjaList
?scala.collection.JavaConversions
? Jeśli tak, widzisz powód, dla którego zalecamJavaConverters
zamiast tego:dm
idk
są konwertowane na kolekcję Java, a następnieadd
metodę wywoływaną w tej kolekcji. Gorzejdm
idk
nie są modyfikowane, nawet jeśli nie pojawił się błąd. I, przy okazji, błąd jest to, że1 -> "ok"
jestMap[Int,String]
, nieMap[String, Object]
.Odpowiedzi:
Listy Scala są domyślnie niezmienne. Nie możesz „dodać” elementu, ale możesz utworzyć nową listę, dołączając nowy element na początku. Ponieważ jest to nowa lista, musisz ponownie przypisać odniesienie (więc nie możesz użyć wartości).
var dm = List[String]() var dk = List[Map[String,AnyRef]]() ..... dm = "text" :: dm dk = Map(1 -> "ok") :: dk
Operator
::
tworzy nową listę. Możesz także użyć krótszej składni:dm ::= "text" dk ::= Map(1 -> "ok")
NB: W SCALA nie użyć typu
Object
aleAny
,AnyRef
alboAnyVal
.źródło
List
jest niezmienna. To zalecany do większości zastosowań.mutable.List
-List
jest typem konkretnym, którego jedyna implementacja jest niezmienna. Istnieją niezmienne klasy, takie jakLinkedList
iDoubleLinkedList
, które są w większości klasami pomocniczymi. Odpowiednikiem Javy w ScaliArrayList
jestArrayBuffer
, a odpowiednikiem JavyLinkedList
jestListBuffer
. Cechą, która odpowiada Javie,List
jestSeq
- której istniejecollection.Seq
i, rozszerzając ją,collection.immutable.Seq
icollection.mutable.Seq
.::=
i+=
?::
jest zdefiniowane, więc+=
nie będzie działać. W innej kolekcji (nie w standardowej bibliotece lib): jeśli implementacja::=
lub+=
jest zaimplementowana, zostanie użyta. W przeciwnym razie kompilator zamieni sięx::=y
wx = y::x
ix+=y
inrox=x+y
. W drugim przypadku są takie same, jeśli realizacja::
jest taka sama jak realizacja+
...Jeśli chcesz zmutować coś, użyj
ArrayBuffer
lubLinkedBuffer
zamiast tego. Jednak lepiej byłoby odnieść się do tego stwierdzenia:Zamiast tego wypełnić listę kodem, który zwraca elementy. Jest na to wiele sposobów i podam kilka przykładów:
// 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
źródło
Jak wszyscy już wspominali, nie jest to najlepszy sposób korzystania z list w Scali ...
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
źródło
list ::= "text"
to O (1), które jest stałe i najlepsze, co możesz zrobić.Jak wspomniano w powyższej odpowiedzi , lista Scala jest niezmienną kolekcją. Możesz utworzyć pustą listę za pomocą
.empty[A]
. Następnie można użyć metody:+
,+:
lub::
w celu dodania elementu do listy.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))
źródło
Domyślnie kolekcje w scali są niezmienne, więc masz metodę +, która zwraca nową listę z dodanym do niej elementem. Jeśli naprawdę potrzebujesz czegoś takiego jak metoda dodawania, potrzebujesz zmiennej kolekcji, np. Http://www.scala-lang.org/api/current/scala/collection/mutable/MutableList.html, która ma metodę + =.
źródło
Może możesz użyć ListBuffers w scali, aby utworzyć pustą listę i dodać ciągi później, ponieważ ListBuffers są mutowalne. Również wszystkie funkcje List są dostępne dla ListBuffers w scali.
import scala.collection.mutable.ListBuffer val dm = ListBuffer[String]() dm: scala.collection.mutable.ListBuffer[String] = ListBuffer() dm += "text1" dm += "text2" dm = ListBuffer(text1, text2)
jeśli chcesz, możesz przekonwertować to na listę za pomocą .toList
źródło
W twoim przypadku używam:
val dm = ListBuffer[String]()
ival dk = ListBuffer[Map[String,anyRef]]()
źródło