Scala,Java和平等

val filesHere = (new java.io.File(".")).listFiles val filesHere2 = (new java.io.File(".")).listFiles 

scala> filesHere == filesHere2
res0:Boolean = false

这非常直观。 我宁愿期望filesHere和filesHere2相等。

这肯定是由于Java和Scala之间的语义不匹配,例如,关于数组或(文件)相等。 显然,我在这里遗漏了一些东西!

您可能想通读这里:

http://ofps.oreilly.com/titles/9780596155957/AdvancedObjectOrientedProgramming.html#EqualityOfObjects

但似乎你做了: filesHere.sameElements(filesHere2) ,它应该是真的。

这里的javadoc在这里: http : //www.scala-lang.org/api/2.6.0/scala/IterableProxy.html#sameElements%28Iterable%5BB%5D%29

更新:

来自第一个链接的几个片段可能会有所帮助:

在Java,C ++和C#中,==运算符测试以供参考,而不是值相等。 相比之下,Ruby的==运算符测试值相等。 无论您习惯使用哪种语言,请务必记住在Scala中,==正在测试价值平等。

参考==在列表中未按预期工作:

虽然这看似不一致,但鼓励对两个可变数据结构的相等性进行明确测试是语言设计者的保守方法。 从长远来看,它可以帮助您避免条件下的意外结果。

更新2:

根据Raphael的评论,我查看了规范,并在两天前发布了最新的更新,我在http://www.scala-lang.org/files/archive/nightly/pdfs/ScalaReference看到了这些内容。 .pdf :

 Method equals: (Any)Boolean is structural equality, where two instances are equal if they both belong to the case class in question and they have equal (with respect to equals) constructor arguments. class AnyRef extends Any { def equals(that: Any): Boolean = this eq that final def eq(that: AnyRef): Boolean = . . . // reference equality 

因此,似乎Scala 2.10.2中的定义没有改变,因为规范似乎是一致的。 如果行为不同,那么如果您编写unit testing,则应将其作为Scala的错误发送。

如果我统治世界,我会弃用Scala的eq方法,因为名称与equals和== 极其混淆。 相反,英语确实有一个表达身份而不是平等的词:我只是称之为。

同样地,我会用isnt替换Scala的ne (这是一个可怕的名字,因为它既是缩写又是不可理解的)。

在我看来,这些实际上可以添加到AnyRef中,并且旧方法已被弃用,即使在这个后期阶段也是如此。

Java数组的equals()方法使用引用相等而不是更复杂的东西,而Scala的==只是Java的equals()

比较不能按预期工作,因为此Java API返回一个Array。

Scala的数组和Java数组在幕后是相同的,尽管Scala的数组看起来像一个类,但它只是一个java.io.File [](在本例中)。

这就是无法覆盖检查相等性的原因。 Scala必须使用Java语义。

考虑这个例子:

 val filesHere = (new java.io.File(".")).listFiles.toList val filesHere2 = (new java.io.File(".")).listFiles.toList 

这将按预期工作。