5 ответов:
вы обычно используете
==, Он направляет кequals, за исключением того, что он лечитnulls правильно. Равенство ссылок (редко используется) -eq.
==является окончательным методом и вызывает.equals, которое не является окончательным.это радикально отличается от Java, где
==является оператором, а не методом и строго сравнивает ссылочное равенство для объектов.
TL; DR
- переопределить
equalsметод для сравнения содержимого каждого экземпляра. Это то же самоеequalsметод, используемый в Java- использовать
==оператор для сравнения, не беспокоясь оnullссылки- использовать
eqметод, чтобы проверить, если оба аргумента являются ровно та же ссылка. Не рекомендуется использовать, если вы не понимаете, как это работает и частоequalsбудет работать для того, что вам нужно вместо этого. И убедитесь в этом используйте это только сAnyRefаргументы, а не простоAnyПримечание: На случай
equals, как и в Java, он может не возвращать тот же результат, если вы переключаете аргументы, например1.equals(BigInt(1))вернутсяfalseгде обратное возвратитсяtrue. Это связано с тем, что каждая реализация проверяет только определенные типы. Примитивные числа не проверяют, является ли второй аргументNumber, ниBigIntтипы, но только другие примитивные типыподробности
The
AnyRef.equals(Any)метод-это тот, который переопределяется подклассами. Метод из спецификации Java, который также перешел на Scala. Если используется на распакованном экземпляре, он помещается в коробку, чтобы вызвать это (хотя скрыто в Scala; более очевидно в Java сint->Integer). Реализация по умолчанию просто сравнивает ссылки (как в Java)The
Any.==(Any)метод сравнивает два объекта и позволяет любому аргументу быть null (как будто вызывая a статический метод с двумя экземплярами). Он сравнивает, если обаnull, затем он вызываетequals(Any)метод экземпляра в упаковке.The
AnyRef.eq(AnyRef)метод сравнивает только ссылки, то есть, где экземпляр находится в памяти. Для этого метода нет неявного бокса.примеры
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, так как оба аргумента ссылаются на одну и ту же ссылку
есть интересная разница между
==иequalsнаFloatиDoubleтипы: они относятся кNaNиначе:scala> Double.NaN == Double.NaN res3: Boolean = false scala> Double.NaN equals Double.NaN res4: Boolean = trueEdit: как было указано в комментарии - "это также происходит в 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)); }выводит
false true trueИтак,
unboxedNanдоходностьfalseпри сравнении для равенства, потому что именно так определяют числа с плавающей запятой IEEE это и должно действительно происходить в каждом языке программирования (хотя это как-то путает с понятием идентичности).коробочный NaN дает true для сравнения с использованием
==в Java, как мы сравниваем ссылки на объекты.у меня нет объяснений
equalsслучай, имхо он действительно должен вести себя так же, как==на распакованных двойных значениях, но это не так.в переводе на Scala вопрос немного сложнее, чем Scala объединил примитивные и объектные типы в
Anyи переводится в примитивный двойной и коробочный двойной по мере необходимости. Таким образом, скала==видимо, сводится к сравнению примитивныхNaNзначения аequalsиспользует тот, который определен на коробочных двойных значениях (существует много неявной магии преобразования, и есть вещи, которые сводятся на двойникиRichDouble).если вам действительно нужно узнать, если что-то на самом деле
NaNиспользоватьisNaN:
Comments