开发者

Scala Case Class equals implementation

Given the following the classes:

trait ModelWithId {
  var id: Long = 0
}
case class EntityAttribute  (
  val entityId: UUID,
  val attrName: String,
  val stringVal: Option[String],
  val boolVal: Option[Boolean],
  val longVal: Option[Long],
  val doubleVal: Option[Double],
  val byteVal: Option[Array[Byte]]) extends ModelWithId{
  override def toString() : String = {
"EntityAttribute(" + entityId.hashCode + "," + attrName.hashCode + "," +
  stringVal.map{_.hashCode}.getOrElse(None) + "," + stringVal.hashCode+ "," +
  boolVal.map{_.hashCode}.getOrElse(None) + "," + boolVal.hashCode+ "," +
  longVal.map{_.hashCode}.getOrElse(None) + "," + longVal.hashCode+ "," +
  doubleVal.map{_.hashCode}.getOrElse(None) + "," + doubleVal.hashCode+ "," +
  byteVal.map{_.hashCode}.getOrElse(None) +  ")"
  }
}

And the following comparison functions:

val newAtttributes : List[EntityAttribute]
val withoutIds : List[EntityAttribute]

println("without: " + withoutIds)
println("new:     " + newAtttributes)

  val differences = newAtttributes.diff(withoutIds)
  println("diff:    " + differences)
  if(newAtttributes.size == 1 && withoutIds.size == 1){
    println("==:      " + (newAtttributes.get(0) == withoutIds.get(0)))
    println("equals:  " + (newAtttributes.get(0).equals(withoutIds.get(0))))
    println("hequals: " + (newAtttributes.get(0).hashCode == withoutIds.get(0).hashCode))
  }

I get the expected difference output 99 out 100 times. Very occasionally the diff function will return an empty list when it should a list of one.

Example:

without: List(EntityAttribute(428861607,-1147340381,None,120224,None,120224,56,-356863126,None,120224,None))
new:     List(EntityAttribute(428861607,-1147340381,None,120224,None,120224,23,424930523,None,120224,None))
diff:    List()
==:      false
equals:  false
hequals: false

I can reliably reproduce this error usually after around 10-18 iterations. The two lists are coming from different sources, so they are being constructed differently. I am guessing that it has something to do with auto-boxing开发者_JS百科 or a bad hashCode implementation but I have been bashing my head into a wall for 2 days without progress.

I'm using scala 2.9.0-1.


Those two EntityAttribute's contain different values for longVal. The default equals implementation for case classes takes all members into account, so that makes them unequal. If you want to only use a subset of the members you should define your own equals and hashCode.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜