Scala 为什么在“map”中多次调用时只创建一个新对象?

Scala 为什么在“map”中多次调用时只创建一个新对象?,scala,Scala,据我所知,用一个元素创建一个新的ArrayBuffer的方法是 val buffer = ArrayBuffer(element) 或者像这样: val buffer = ArrayBuffer[Option[String]](None) 假设x是一个包含3个元素的集合。我正在尝试创建一个映射,为x中的每个元素创建一个新的1元素ArrayBuffer,并将x中的元素与新缓冲区关联。(这些是有意分离的可变缓冲区,将由线程修改。)我尝试了以下方法: x.map(elem => (elem,

据我所知,用一个元素创建一个新的
ArrayBuffer
的方法是

val buffer = ArrayBuffer(element)
或者像这样:

val buffer = ArrayBuffer[Option[String]](None)
假设
x
是一个包含3个元素的集合。我正在尝试创建一个映射,为
x
中的每个元素创建一个新的1元素
ArrayBuffer
,并将
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
,则地图中只有一个元素(因为所有元素都具有相同的键)

我打开了一点(删除
.toMap
,您将有3个
字节数组


如果我误解了你,请告诉我

例如,我似乎无法复制这个问题

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)
)

我们看到
一些(“42”)
被添加到一个缓冲区,而其他缓冲区未受影响。

您确定只创建了一个缓冲区吗?如果在第一个缓冲区中添加一个元素,它会出现在其他两个缓冲区中吗?@ajb您能否提供完整的最小示例,说明如何使用
identityHashCode
?您是否意外地使用了
ArrayBuffer
内容的
identityHashCode
?如果没有办法重现这个问题,恐怕没有什么用处。