Scala List.contains(x) return false, but exists(_.== x) returns true

collections, contains, exists, list, scala

Solution

You are not overriding the actual equals method of Scala, that is why it behaves strangely. Re-write your equals method as this, and things should work:

override def equals (other: Any) : Boolean = {
    other match{
      case that: State =>
        //println("Comparing " + trackmap + " to " + other.trackmap)
        trackmap == that.trackmap
      case _ => false
    }
}

See, equals method in Scala takes a parameter of type Any not State, and you need to add the `override` keyword for it.

BTW, you don't even need the == method, as Scala automatically remaps it to equals method!

Problem

I'm working with some simple data structures and collections in Scala and I've noticed what I think is strange behavior. Here's the object: ``` class State (protected val trackmap: Map[Int, List[String]]) { override def clone : State = { new State(Map() ++ trackmap) } override def toString = { "State: " + trackmap.toString } def equals (other: State) : Boolean = { //println("Comparing " + trackmap + " to " + other.trackmap) trackmap == other.trackmap } def == (other: State) : Boolean = { this equals other } } ``` And my related tests: ``` test("state equality") { val state = new State( Map(1 -> List("engine"), 2 -> List("a"), 3 -> List("b")) ) expect(true) { state equals state.clone } expect(true) { state == state.clone } expect(false) { state == new State(Map(1 -> List("a"))) } expect(false) { state equals new State(Map(1 -> List("a"))) } expect(true) { List(state).exists( _.equals (state.clone) )} expect(true) { List(state).exists( _.== (state.clone) )} expect(true) { List(state).contains( state.clone )} } ``` All of them pass except for the last one, which I expect should pass. I haven't looked at the Scala source, but I assume contains would be implemented basically as the second exists call.

Original source