我有以下案例类
case class Something(val input : Array[Int], val output : Array[Int] = null, val remainder : Array[Int] = null, val next : Something = null) {
override def equals(thatGeneric: scala.Any): Boolean = {
if(!thatGeneric.isInstanceOf[Something])
return false
val that = thatGeneric.asInstanceOf[Something]
val thisInput = if(this.input == null) null else this.input.deep
val thatInput = if(that.input == null) null else that.input.deep
val thisOutput = if(this.output == null) null else this.output.deep
val thatOutput = if(that.output == null) null else that.output.deep
val thisRemainder = if(this.remainder == null) null else this.remainder.deep
val thatRemainder = if(that.remainder == null) null else that.remainder.deep
return (thisInput,thisOutput,thisRemainder,this.next) == (thatInput,thatOutput,thatRemainder,that.next)
}
/**
* TODO fix hashcode in case I want to use this in collection
* @return
*/
override def hashCode(): Int = super.hashCode()
}
我知道case类应该为你创建你的equals和hashCode方法,但是对于Arrays,因为==
不起作用,所以我想这就是为什么它对我的case类不起作用。
有没有更好的方法可以不必为我的case类手写我的equals和hashCode方法?
注意:我也欢迎有关为什么/如何改进我当前的equals方法的建议
编辑:一般都喜欢关于我使用case类的注释,但我的问题基本上是:假设你的case类中需要一个Array,你如何避免滚动你自己的equals和hashCode。 (如果答案是不可能的,我需要使用一个列表,那就是答案,只是不确定是这种情况。)
答案 0 :(得分:2)
数组确实更轻,但不幸的是,scala并没有为数组的大多数方法重新实现,因此它们最终共享了通用(sucky)scala集合性能属性。
只要你开始使用数组,你就必须实现自己的equals
,你可以做的不多,但你可以让它看起来更漂亮,如下所示: / p>
def eq[T](a: Array[T], b: Array[T]) = Option(a.toSeq) == Option(b.toSeq)
def equals(that: Something) =
eq(input, that.input) &&
eq(output, that.output) &&
eq(remainder, that.remainder) &&
next == that.next
你应该考虑让你的变量可选。就像每个人都说的那样,null
并不会在scala中给你取得任何分数。
此外,再次像其他人一样说,重新考虑将您的案例类作为一个类:使用案例类的重点是免费获得equals
和hashCode
(以及其他一些东西)。如果你打算重新实现所有这一切,如果只是混淆而宣布它为案例类,并且没有任何好处。
答案 1 :(得分:1)
这个类定义似乎有些问题。使用null
s,var
和Array
s。
正如@m-z所提到的,案例类旨在用作“数据”类。应该是不可变的数据。如果您不想滚动自己的equals
和hashCode
,那么您应该重新考虑实施。
注意:不确定您要使用此类的内容,但可能存在可能符合您需求的设计模式,并坚持使用案例类。