다음과 같은 코드가 있습니다.
val dm = List[String]()
val dk = List[Map[String,Object]]()
.....
dm.add("text")
dk.add(Map("1" -> "ok"))
그러나 런타임 java.lang.UnsupportedOperationException이 발생합니다.
빈 목록이나 빈지도를 선언해야하며 나중에 코드에서 채워야하는 일부도 있습니다.
다음과 같은 코드가 있습니다.
val dm = List[String]()
val dk = List[Map[String,Object]]()
.....
dm.add("text")
dk.add(Map("1" -> "ok"))
그러나 런타임 java.lang.UnsupportedOperationException이 발생합니다.
빈 목록이나 빈지도를 선언해야하며 나중에 코드에서 채워야하는 일부도 있습니다.
scala.collection.JavaConversions
? 당신이 한 경우에, 당신은 내가 추천하는 이유는 바로 그 이유보고있다 JavaConverters
: 대신 dm
하고 dk
다음 자바 콜렉션으로 전환되고 있으며, add
그 컬렉션이라는 방법을. 더 나쁜, dm
그리고는 dk
당신이 오류가 발생하지 않은 경우에도 수정되지 않습니다. 그리고, 그런데, 오류가 즉 1 -> "ok"
있다 Map[Int,String]
, 없다 Map[String, Object]
.
답변:
스칼라 목록은 기본적으로 변경할 수 없습니다. 요소를 "추가"할 수 없지만 앞에 새 요소를 추가하여 새 목록을 만들 수 있습니다. 그것이이기 때문에 새로운 목록, 당신은 (당신이 발을 사용할 수 있도록) 참조를 다시 할당해야합니다.
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 : 에이 형식을 사용하지 않는 스칼라 Object
하지만 Any
, AnyRef
또는 AnyVal
.
List
불변입니다. 대부분의 사용에 권장되는 것입니다.
mutable.List
- List
가없는 구체적인 유형이며 유일한 구현은 변경할 수 없습니다. 같은 불변 클래스가 있습니다 LinkedList
및 DoubleLinkedList
대부분의 헬퍼 클래스입니다. Java에 해당하는 Scala ArrayList
는 ArrayBuffer
이고 Java에 해당하는 LinkedList
것은 ListBuffer
. 형질 자바의에 해당이 있다는 List
것입니다 Seq
- 어느 거기 collection.Seq
를 확장하고, collection.immutable.Seq
하고 collection.mutable.Seq
.
::=
및 +=
?
::
정의되므로 +=
작동하지 않습니다. 다른 컬렉션 (표준 라이브러리가 아님) : ::=
또는 +=
구현 된 경우 구현이 사용됩니다. 그 밖에, 컴파일러는 켜집니다 x::=y
로 x = y::x
하고 x+=y
inro 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)이며 이는 일정하며 최선을 다합니다.
이상에서 언급 한 바와 같이 대답 의 스칼라 목록 불변의 모음입니다. 를 사용하여 빈 목록을 만들 수 있습니다 .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))
스칼라의 기본 컬렉션은 변경할 수 없으므로 요소가 추가 된 새 목록을 반환하는 + 메서드가 있습니다. add 메소드와 같은 것이 정말로 필요한 경우 + = 메소드가있는 http://www.scala-lang.org/api/current/scala/collection/mutable/MutableList.html 과 같이 변경 가능한 콜렉션이 필요합니다 .
스칼라에서 ListBuffers를 사용하여 빈 목록을 만들고 나중에 문자열을 추가 할 수 있습니다. ListBuffer는 변경 가능하기 때문입니다. 또한 모든 List 함수는 스칼라의 ListBuffer에 사용할 수 있습니다.
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를 사용하여 이것을 목록으로 변환 할 수 있습니다.
add
작업이에List
?