【问题标题】:Scala Immutable Map returns different values for same keyScala 不可变映射为同一个键返回不同的值
【发布时间】:2013-10-08 23:29:40
【问题描述】:

我有一个应用程序在 scala.collection.immutable.Map 中使用相同的键进行连续查找,这会导致返回两个不同的引用。类似于以下内容:

val v1 = m(key)
val v2 = m(key)
require(v1 eq v2) // fails!

我无法在一个小示例中重现此行为,我想知道是否有任何情况可以合理/预期。该应用程序是单线程的,我通过一个接一个地进行查找来隔离问题。

【问题讨论】:

  • 你有并发吗?你有副作用 hashcodeequals 方法吗?
  • 应用程序是顺序的(无并发)。 hashcodeInt val(每个对象唯一),equals 比较 hashcode 的值。

标签: scala map reference immutability


【解决方案1】:

我怀疑您正在测试引用相等性。在这种情况下,v1 和 v2 是不同的对象。除非您创建案例类,否则引用相等是类的默认设置。

【讨论】:

  • 但是 v1 和 v2 应该是同一个对象。如果他使用get,那将是一个不同的故事(不同的Option 实例)
  • Luigi - 我也希望返回的值是相同的。尽管equals 下的值是等效的,但它们的引用(由eq 测试)不是。
【解决方案2】:

您的地图是否有可能是不可变的,但您用于它的键是可变的或有不正确的hashcodeequals 实现返回不确定的结果?您使用的类型是什么?

REPL 中过分夸大的例子:

scala> import scala.util.Random
import scala.util.Random

scala> class BadKey(val value: Int) {
     |   override def hashCode = Random.nextInt(Int.MaxValue)
     | 
     |   override def equals(x: Any) = Random.nextBoolean
     | }
defined class BadKey

scala> val randMap = Map(new BadKey(1) -> 1, new BadKey(2) -> 2)
randMap: scala.collection.immutable.Map[BadKey,Int] = Map(BadKey@26132448 -> 1,     BadKey@41e1cd27 -> 2)

scala> randMap.get(new BadKey(1))
res6: Option[Int] = Some(1)

scala> randMap.get(new BadKey(1))
res7: Option[Int] = Some(2)

scala> randMap.get(new BadKey(1))
res8: Option[Int] = Some(1)

scala> randMap.get(new BadKey(1))
res9: Option[Int] = Some(1)

scala> randMap.get(new BadKey(1))
res10: Option[Int] = Some(1)

scala> randMap.get(new BadKey(1))
res11: Option[Int] = None

【讨论】:

  • 键是可变的(包含var 字段),但它们在两个apply 调用之间不会发生变异。 hashcodeequals 方法是确定性的,它们被实现为仅依赖于对象的一个​​ val 字段,并且每个对象都有该字段的唯一值。
猜你喜欢
  • 2018-02-28
  • 1970-01-01
  • 2018-03-21
  • 1970-01-01
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多