Checking if a Map contains a key of class type in Scala

Viewed 126

I'm new to Scala, and there's something I'm having trouble figuring out. I have the following method:

def updateSongCount(song : Song) {
   if(this.listeningCountMap.contains(song)) {
     this.listeningCountMap(song) += 1
   } 
   else 
   {
     this.listeningCountMap += (song -> 1)
   }
  }

listeningCountMap is defined like this:

var listeningCountMap = Map[Song, Int]()

Now, the thing is Song is a class type and it has several parameters (like title, singer, etc). When I do the contains, even if all the parameters are the same between the two songs - it adds them as two seperate entries. I'm coming from C# and I'm used to having to override GetHashCode and Equals in order for contains to understand when two instances of my class are considered equal, and I suppose what I'm missing is the equivalent for that in scala. Could you please tell me how do we do that in Scala? Thanks!

1 Answers

If Song is defined as case class then equals and hashCode method is generated by the compiler using primary constructor parameters:

case class Song(id: Int, title: String)

In this example equals and hashCode considers both id and title fields.

In case you don't need using all fields for comparison you can just override equals/hashCode methods:

case class Song(id: Int, title: String) {
  override def hashCode() = title.hashCode()

  override def equals(obj: Any) = title.equals(if (obj != null) obj.asInstanceOf[Song].title else null)
}
Related