为什么只有一个新对象在`map`中被多次调用?

问题描述 投票:-1回答:2

据我所知,用一个元素创建新的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。因此,生成的映射只有一对键值对。

抱歉无法尽快解决。一会儿我将删除问题。

scala
2个回答
1
投票

我认为您的问题是toMap。如果所有三个元素均为None,则您在Map中只有一个元素(因为所有元素都具有相同的键)。

我在Scalafiddle上玩了一点(删除.toMap,您将有3个ByteArrays

让我知道我是否误解了你。


1
投票

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

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")被添加到一个缓冲区,而其他缓冲区不受影响。

© www.soinside.com 2019 - 2024. All rights reserved.