我有这样的代码:
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
被转换成Java集合,然后add
叫上采集方法。更糟的是,dm
并dk
没有被修改,即使你没有得到一个错误。而且,顺便说一句,错误1 -> "ok"
是Map[Int,String]
,不是Map[String, Object]
。
Answers:
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")
注:在Scala中不使用的类型Object
,但是Any
,AnyRef
还是AnyVal
。
List
是一成不变的。这是推荐用于大多数用途的一种。
mutable.List
-List
是具体类型,唯一的实现是不可变的。有不可变的类,例如LinkedList
和DoubleLinkedList
,大多数是辅助类。斯卡拉相当于Java的的ArrayList
是ArrayBuffer
,和Java的相当于LinkedList
是ListBuffer
。与Java相对应的特征List
是Seq
-具有,collection.Seq
并且扩展了Javacollection.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),它是常量,是您可以做的最好的事情。
如上面的答案所述,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中的默认集合是不可变的,因此您可以使用+方法返回一个新列表,并在其中添加元素。如果您确实需要诸如add方法之类的东西,则需要一个可变的集合,例如http://www.scala-lang.org/api/current/scala/collection/mutable/MutableList.html具有+ =方法。
也许您可以在scala中使用ListBuffers创建空列表并稍后添加字符串,因为ListBuffers是可变的。而且,所有列表函数都可用于scala中的ListBuffers。
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
?