Scala 中的 == 和 .equals 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7681161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between == and .equals in Scala?
提问by Jus12
What is the difference between ==and .equals()in Scala, and when to use which?
是什么区别==和.equals()Scala中,当使用哪个?
Is the implementation same as in Java?
实现和Java一样吗?
EDIT: The related question talks about specific cases of AnyVal. The more general case is Any.
编辑:相关问题讨论了AnyVal. 更一般的情况是Any。
回答by Didier Dupont
You normally use ==, it routes to equals, except that it treats nulls properly. Reference equality (rarely used) is eq.
您通常使用==, 它路由到equals,除了它null正确对待s 。引用相等(很少使用)是eq.
回答by Don Roby
==is a final method, and calls .equals, which is not final.
==是一个 final 方法,并调用.equals,这不是 final。
This is radically different than Java, where ==is an operator rather than a method and strictly compares reference equality for objects.
这与 Java 完全不同,Java==是运算符而不是方法,并且严格比较对象的引用相等性。
回答by zjohn4
TL;DR
TL; 博士
- Override
equalsmethod to compare content of each instance. This is the sameequalsmethod used in Java - Use
==operator to compare, without worrying aboutnullreferences - Use
eqmethod to check if both arguments are EXACTLYthe same reference. Recommended not to use unless you understand how this works and oftenequalswill work for what you need instead. And make sure to only use this withAnyRefarguments, not justAny
- 覆盖
equals方法以比较每个实例的内容。这与equalsJava 中使用的方法相同 - 使用
==运算符进行比较,无需担心null引用 - 使用
eq的方法来检查,如果两个参数是EXACTLY相同的参考。建议不要使用,除非您了解它是如何工作的,并且通常equals可以满足您的需要。并确保仅将其与AnyRef参数一起使用,而不仅仅是Any
NOTE: On the case of equals, just as in Java, it may not return the same result if you switch the arguments eg 1.equals(BigInt(1))will return falsewhere the inverse will return true. This is because of each implementation checking only specific types. Primitive numbers dont check if the second argument is of Numbernor BigInttypes but only of other primitive types
注意:在 的情况下equals,就像在 Java 中一样,如果您切换参数,它可能不会返回相同的结果,例如1.equals(BigInt(1))will return falsewhere inverse will return true。这是因为每个实现只检查特定类型。原始数字不检查第二个参数是否属于NumbernorBigInt类型而仅属于其他原始类型
Details
细节
The AnyRef.equals(Any)method is the one overridden by subclasses. A method from the Java Specification that has come over to Scala too. If used on an unboxed instance, it is boxed to call this (though hidden in Scala; more obvious in Java with int->Integer). The default implementation merely compares references (as in Java)
该AnyRef.equals(Any)方法是由子类覆盖的方法。Java 规范中的一种方法也已经转移到 Scala 中。如果在未装箱的实例上使用,它会被装箱调用(尽管在 Scala 中隐藏;在 Java 中使用int->更明显Integer)。默认实现仅比较引用(如在 Java 中)
The Any.==(Any)method compares two objects and allows either argument to be null (as if calling a static method with two instances). It compares if both are null, then it calls the equals(Any)method on boxed instance.
该Any.==(Any)方法比较两个对象并允许任一参数为空(就像调用具有两个实例的静态方法一样)。它比较两者是否都是null,然后它调用equals(Any)盒装实例上的方法。
The AnyRef.eq(AnyRef)method compares onlyreferences, that is where the instance is located in memory. There is no implicit boxing for this method.
该AnyRef.eq(AnyRef)方法只比较引用,即实例在内存中的位置。此方法没有隐式装箱。
Examples
例子
1 equals 2will returnfalse, as it redirects toInteger.equals(...)1 == 2will returnfalse, as it redirects toInteger.equals(...)1 eq 2will not compile, as it requires both arguments to be of typeAnyRefnew ArrayList() equals new ArrayList()will returntrue, as it checks the contentnew ArrayList() == new ArrayList()will returntrue, as it redirects toequals(...)new ArrayList() eq new ArrayList()will returnfalse, as both arguments are different instancesfoo equals foowill returntrue, unlessfooisnull, then will throw aNullPointerExceptionfoo == foowill returntrue, even iffooisnullfoo eq foowill returntrue, since both arguments link to the same reference
1 equals 2将返回false,因为它重定向到Integer.equals(...)1 == 2将返回false,因为它重定向到Integer.equals(...)1 eq 2不会编译,因为它要求两个参数都是类型AnyRefnew ArrayList() equals new ArrayList()将返回true,因为它会检查内容new ArrayList() == new ArrayList()将返回true,因为它重定向到equals(...)new ArrayList() eq new ArrayList()将返回false,因为两个参数是不同的实例foo equals foo将返回true,除非foo是null,然后将抛出NullPointerExceptionfoo == foo会返回true,即使foo是nullfoo eq foo将返回true,因为两个参数都链接到同一个引用
回答by scravy
There is an interesting difference between ==and equalsfor Floatand Doubletypes: They treat NaNdifferently:
==和equalsforFloat和Double类型之间有一个有趣的区别:它们的处理方式NaN不同:
scala> Double.NaN == Double.NaN
res3: Boolean = false
scala> Double.NaN equals Double.NaN
res4: Boolean = true
Edit:As was pointed out in a comment - "this also happens in Java" - depends on what exactly thisis:
编辑:正如指出的评论- “这也恰好在Java中” -取决于正是这就是:
public static void main(final String... args) {
final double unboxedNaN = Double.NaN;
final Double boxedNaN = Double.valueOf(Double.NaN);
System.out.println(unboxedNaN == unboxedNaN);
System.out.println(boxedNaN == boxedNaN);
System.out.println(boxedNaN.equals(boxedNaN));
}
This will print
这将打印
false
true
true
So, the unboxedNanyields falsewhen compared for equality because this is how IEEE floating point numbers define it and this should really happen in every programming language (although it somehow messes with the notion of identity).
所以,当比较相等时的unboxedNan收益false,因为这是 IEEE 浮点数定义它的方式,这应该在每种编程语言中真正发生(尽管它以某种方式与身份的概念混淆)。
The boxed NaN yields true for the comparison using ==in Java as we are comparing object references.
==当我们比较对象引用时,装箱的 NaN 对于在 Java 中使用的比较结果为真。
I do not have an explanation for the equalscase, IMHO it really should behave the same as ==on unboxed double values, but it does not.
我没有对这种equals情况的解释,恕我直言,它的行为确实应该与未==装箱的 double 值相同,但事实并非如此。
Translated to Scala the matter is a little more complicated as Scala has unified primitive and object types into Anyand translates into the primitive double and the boxed Double as needed. Thus the scala ==apparently boils down to a comparison of primitive NaNvalues but equalsuses the one defined on boxed Double values (there is a lot of implicit conversion magic going on and there is stuff pimped onto doubles by RichDouble).
转换为 Scala 的情况稍微复杂一些,因为 Scala 已将原始类型和对象类型统一为Any并根据需要转换为原始双精度型和装箱双精度型。因此,scala==显然归结为原始NaN值的比较,但equals使用了在盒装 Double 值上定义的值(有很多隐式转换魔法在进行,并且有一些东西被拉到了 double 上RichDouble)。
If you really need to find out if something is actually NaNuse isNaN:
如果您真的需要确定是否实际NaN使用了某些东西isNaN:
回答by Hyman
In Scala ==first check for Nullvalues and then calls equalsmethod on first object
在 Scala ==首先检查Null值,然后在第一个对象上调用equals方法

