Arrays 数组的Case类相等

Arrays 数组的Case类相等,arrays,scala,case-class,Arrays,Scala,Case Class,我有下面的案例课 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[Someth

我有下面的案例课

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方法,但是对于数组,因为
=
不起作用,所以我想这就是为什么我的case类不起作用的原因

有没有更好的方法不必为case类手工编写equals和hashCode方法

注意:我也欢迎关于为什么/如何改进我目前的equals方法的建议


编辑:非常感谢关于我使用case类的注释,但我的问题基本上是:假设您的case类中需要一个数组,那么如何避免使用自己的equals和hashCode呢。(如果答案是这是不可能的,我需要使用一个列表,那么这就是答案,只是不确定情况是否如此。)

这个类定义似乎有几处错误。使用
null
s、
var
s和
Array
s

正如@m-z提到的,case类打算用作“数据”类。应该是不可变的数据。如果您不想使用自己的
equals
hashCode
进行滚动,那么您应该重新考虑实现


注意:不确定您试图使用该类的目的是什么,但可能有一种设计模式符合您的需要并符合案例类的真正用途。

数组确实更轻,但不幸的是,没有太多(scala没有重新实现该数组的大多数方法,因此它们最终共享泛型(糟糕)scala集合性能属性

只要您开始使用数组,您就必须实现自己的
equals
,对此您无能为力,但您可以使它看起来更漂亮,如下所示:

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中给你任何分数。


同样,正如其他人所说,重新考虑将您的case类作为一个类:使用case类的全部目的是获得
等于
hashCode
(以及其他一些东西)免费。如果你打算重新实现所有这些,如果只是混淆,就把它声明为一个case类,没有任何好处。

你想使用
数组而不是
列表,有什么原因吗?
?case类传统上是用来保存一个不可变的数据结构。实际上它是不可变的,我最初把它作为
变量
s但是它们可以是
val
s没有问题。不确定
nulls
Array
s的问题是什么意思。你能解释一下吗?你可以使用
val
,但数组本身仍然是可变的。显然,你希望在计算hashcode时考虑数组的内容,但在这里问题在于:此内容可能会更改,这会更改哈希代码,并破坏
hashcode
方法的约定(“在Java应用程序执行期间,每当在同一对象上多次调用它时,hashcode方法必须始终返回相同的整数”,请参阅)@RégisJean Gilles这不是使用可变类型作为您案例类的参数的问题。例如,您可以使用
mutable.Seq
,具有相同内容的案例类仍然是相等的。这是如何为
数组
迭代器
实现相等的问题,这是引用相等。看到了吗,我知道^^。我只是在回答OP上面的评论,这表明他认为使用val使数据不可变,而实际上只有引用是不可变的,它指向的数组仍然是非常可变的。这使得在case类中使用数组有风险(因此应该小心)额外数组具有引用相等的事实当然更接近原始问题的要点,但这不是我要回答的(否则我会将其作为答案发布)。