我在Scala中有一张地图var surfaceMap = Map[Surface, Array[Event]]()
,其中Surface
类表示由平面组成的几何曲面。在Surface类中,我定义equals
方法如下:
final override def equals(other: Any): Boolean = other match {
case that: Surface => (planes.deep == that.planes.deep)
case _ => false
}
final override def hashCode: Int = planes.##
等式检查构造曲面的所有平面是否具有相同的坐标。我有一个8个元素的surfaceMap,当我想向地图中已经存在的表面添加Event
时,当我用surfaceMap.contains(newSurface)
检查密钥的存在时,它返回false但是当我使用时surfaceMap.exists(_._1 == newSurface)
或surfaceMap.keySet.exists(_ == newSurface)
需要更长时间才能返回true。我认为.contains()
和.keySet.exists()
做同样的工作,但似乎它们不同,但我不明白其中的区别。任何帮助表示赞赏。
答案 0 :(得分:1)
Map.keySet.exists
与Map.contains
,Map.keySet.contains
的做法不同。
不同之处在于.contains
使用对象的哈希码(提供,我们使用默认的HashMap,实现)来快速导航到您要查找的键。这是一个恒定时间(O(1)
)操作。
.exists
不能这样做,因为它正在寻找任意条件,而不是确切的对象。因此,它必须扫描整个集合并评估每个元素的条件,直到找到匹配的元素。这是一个线性时间(O(N)
)操作。
至于为什么Map.contains
在您的情况下返回false,这必须是因为您的hashCode
实现不正确:您使用的是默认值##
,这对于不同的实例会有所不同,即使它们包含相同的值(除非,它是一个案例类)。