据我所知,用一个元素创建新的ArrayBuffer
的方法是说
val buffer = ArrayBuffer(element)
或类似这样的东西:
val buffer = ArrayBuffer[Option[String]](None)
假设x
是一个包含3个元素的集合。我正在尝试创建一个映射,该映射为ArrayBuffer
中的每个元素创建一个新的1元素x
,并将x
中的元素与新缓冲区关联。 (这些是有意分离的可变缓冲区,这些可变缓冲区将由线程修改。)我尝试过此操作:
x.map(elem => (elem, ArrayBuffer[Option[String]](None))).toMap
但是,我发现(使用System.identityHashCode
)仅创建了一个ArrayBuffer
,并且所有3个元素都映射到相同的值。
为什么会这样?我期望将为x
的每个元素评估元组表达式,并且这将导致为表达式的每个评估创建新的ArrayBuffer
。
什么是好的解决方法?
我正在使用Scala 2.11。
[创建可复制示例的过程中,我发现了问题所在。这是例子; Source
是我们的应用程序中定义的接口。
def test1(x: Seq[Source]): Unit = {
val containers = x.map(elem => (elem, ArrayBuffer[Option[String]](None))).toMap
x.foreach(elem => println(
s"test1: elem=${System.identityHashCode(elem)} container=${System.identityHashCode(containers(elem))}"))
x.indices.foreach(n => containers(x(n)).update(0, Some(n.toString)))
x.foreach(elem => println(s"resulting value: ${containers(elem)(0)}"))
}
[我想念的是,对于我尝试使用的x
的值,对于所有值的组合,实现Source
的类对于equals()
返回的都是true。因此,生成的映射只有一对键值对。
抱歉无法尽快解决。一会儿我将删除问题。
我认为您的问题是toMap
。如果所有三个元素均为None
,则您在Map中只有一个元素(因为所有元素都具有相同的键)。
我在Scalafiddle上玩了一点(删除.toMap
,您将有3个ByteArrays
)
让我知道我是否误解了你。
例如,我似乎无法复制该问题
val m =
List(Some("a"), Some("b"), Some("c"))
.map(elem => (elem, ArrayBuffer[Option[String]](None)))
.toMap
m(Some("a")) += Some("42")
m
输出
res2: scala.collection.immutable.Map[Some[String],scala.collection.mutable.ArrayBuffer[Option[String]]] = Map(
Some(a) -> ArrayBuffer(None, Some(42)),
Some(b) -> ArrayBuffer(None),
Some(c) -> ArrayBuffer(None)
)
[我们看到Some("42")
被添加到一个缓冲区,而其他缓冲区不受影响。