Scala Case Class соответствует реализации - PullRequest
5 голосов
/ 28 июля 2011

Учитывая следующие классы:

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) +  ")"
  }
}

И следующие функции сравнения:

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))
  }

Я получаю ожидаемую разность вывода 99 из 100 раз.Очень редко функция diff будет возвращать пустой список, если ей нужен список из одного.

Пример:

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

Я могу надежно воспроизвести эту ошибку обычно после 10-18 итераций.Два списка приходят из разных источников, поэтому они строятся по-разному.Я предполагаю, что это как-то связано с автобоксом или плохой реализацией hashCode, но я безуспешно врезаю голову в стену в течение 2 дней..

1 Ответ

0 голосов
/ 28 июля 2011

Эти два EntityAttribute содержат разные значения для longVal.Реализация equals по умолчанию для case-классов учитывает все элементы, поэтому они не равны.Если вы хотите использовать только подмножество членов, вы должны определить свои equals и hashCode.

...