Reputation: 145
I have a map var surfaceMap = Map[Surface, Array[Event]]()
in Scala where Surface
class represents geometrical surfaces consisting of planes. In Surface class I define equals
method as follows:
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.##
The equality checks if all the planes that construct the surface has the same coordinates. I have a surfaceMap of 8 elements and when I want to add an Event
to a surface that is already in the map, when I check the existence of the key with surfaceMap.contains(newSurface)
it returns false but when I use surfaceMap.exists(_._1 == newSurface)
or surfaceMap.keySet.exists(_ == newSurface)
it takes longer and returns true. I thought .contains()
and .keySet.exists()
do the same job but it seems that they are different but I don't understand the difference. Any help is appreciated.
Upvotes: 1
Views: 4043
Reputation: 40500
Map.keySet.exists
does not do the same thing as Map.contains
, Map.keySet.contains
does.
The difference is that .contains
uses object's hash code (provided, we are using the default, HashMap, implementation) to quickly navigate to the key you are looking for. This is a constant time (O(1)
) operation.
.exists
cannot do that, because it is looking for an arbitrary condition, not an exact object. So, it has to scan the entire set and evaluate the condition for each element, until it finds the one that matches. This is a linear time (O(N)
) operation.
As to why Map.contains
returns false in your case, that must be because your hashCode
implementation is incorrect: you are using the default .##
, which will be different for different instances, even if they contain the same values (unless, it is a case class).
Upvotes: 5