Разница между равными / равными и == оператором? - PullRequest
44 голосов
/ 09 июня 2009

В чем разница между a == b и a.Equals(b)?

Ответы [ 11 ]

51 голосов
/ 09 июня 2009

Предполагая, что типы a и b являются ссылочными типами:

  • В Java == всегда будет сравнивать для identity - т.е. являются ли два значения ссылками на один и тот же объект. Это также называется ссылочным равенством . В Java нет пользовательских перегрузок операторов.

  • В C # это зависит. Если нет перегруженного оператора, который его обрабатывает, == будет вести себя как Java (т.е. сравнивать по ссылочному равенству). Однако, если есть перегрузка, которая соответствует типам времени компиляции a и b (например, если они оба объявлены как строки), то эта перегрузка будет вызвана. Это может вести себя так, как он хочет, но, как правило, реализует равенство значений (то есть a и b могут ссылаться на разные, но равные значения и все равно будут возвращать true).

На обоих языках a.Equals(b) или a.equals(b) будут вызывать виртуальный метод Equals / equals, объявленный Object, если только более конкретная перегрузка не была введена типом времени компиляции a , Это может или не может быть переопределено в типе времени выполнения объекта, на который ссылается a. И в .NET, и в Java реализация в Object также проверяет подлинность. Обратите внимание, что это зависит от типа времени выполнения , а не от типа времени компиляции , от которого зависит разрешение перегрузки.

Конечно, если a равно null, вы получите NullReferenceException / NullPointerException при попытке позвонить a.equals(b) или a.Equals(b).

13 голосов
/ 09 июня 2009

Оператор == проверяет, являются ли два объекта абсолютно одинаковыми, что в большинстве случаев не подходит. Метод Equals сможет сравнивать оба объекта внутренне

Пример:

class Mycar
{
  string color;
  Mycar(string str)
 {
   color = str;
 }
}   

Mycar a = new Mycar("blue");
Mycar b = new Mycar("blue");
a==b // Returns false
a.Equals(b) // Returns true
3 голосов
/ 09 июня 2009

Зависит от типов a и b.

В частности, Equals - это виртуальный метод, поэтому его поведение не зависит от типов времени компиляции a и b.

В Java == всегда будет сравниваться по ссылке, что не обязательно то, что вы хотите, особенно для строк.

В C # == может быть перегружен, но не является виртуальным (это метод static). Поэтому, если a или b объявлены как object, он будет сравниваться по ссылке, даже если их фактический тип перегружает operator ==.

Кроме того, a.Equals(b) выдаст NullReferenceException (NullPointerException в Java), если a равно null.

2 голосов
/ 09 июня 2009
String a = "toto".Substring(0, 4);
String b = "toto";
Object aAsObj = a;
Assert.IsTrue(a.Equals(b));
Assert.IsTrue(a == b);
Assert.IsFalse(aAsObj == b);
Assert.IsTrue(aAsObj.Equals(b));

Этот проход теста в .NET, уловка в том, что Equals - это метод, тогда как == - это static метод, поэтому aAsObj == b использует

static bool Object.operator==(object a, object b) //Reference comparison

, тогда как a == b использовать

static bool String.operator==(string a, string b) //String comparison

но a.Equals(b) или aAsObj.Equals(b) всегда используйте:

bool String.Equals(Object obj) //String comparison
1 голос
/ 04 декабря 2013

== является основным оператором в языке. Оператор == проверяет, ссылаются ли две переменные ссылки на объект на один и тот же экземпляр объекта.

equals () - это метод экземпляра, который в основном определяется классом java.lang.Object. Метод .equals () проверяет, являются ли два сравниваемых объекта эквивалентными, но они не обязательно должны быть точно такими же экземплярами одного и того же объекта.

Оператор == всегда дает один и тот же результат, но метод equals () дает вывод в соответствии с вашей реализацией (реализованной логикой). Надлежащее переопределение equals: соображения при каждом переопределении метода equals ().

1. Рефлексивный: для любой ненулевой ссылки x, x.equals (x) должен возвращать true.

2. Симметричный: для любых ненулевых ссылок x и y, если x.equals (y) имеет значение true, тогда y.equals (x) должен возвращать true.

3. Транзитивно: для любой ненулевой ссылки x, y и z, если x.equals (y) - true, y.equals (z) - true, тогда x.equals (z) должен вернуть true.

4. Согласованно: для любой ненулевой ссылки x и y множественные вызовы x.equals (y) последовательно возвращают true или последовательно возвращают false, не изменяя информацию, предоставленную для сравнений equals.

5. Для любой ненулевой ссылки x, x.equals (null) должен возвращать false. ПРИМЕЧАНИЕ. Если o1.equals (o2) имеет значение true, тогда o1.hashcode () == o2.hashcode (), но обратное может быть или не быть истинным.

Примеры:

Целое число i = новое целое число (10); Целое число j = i;

в приведенном выше коде. i == j верно, потому что и i, и j ссылаются на один и тот же объект.

целое число i = новое целое число (10); Целое число j = новое целое число (10);

В приведенном выше коде i == j равно FALSE, поскольку, хотя они оба имеют значение 10, они представляют собой два разных объекта. Но i.equals (j) вернет true.

Использование автобокса

Целое число i = 10;
Целое число j = 10;
Логическое b = (i == j);
System.out.println (b);

Это вернет TRUE, поскольку целые числа между диапазонами от -127 до 128 будут объединены, поэтому в этом случае оба объекта будут одинаковыми (JVM не собирается создавать новый объект, он будет извлекать его из пула).

Строковый класс переопределяет метод equals, поэтому здесь приведен пример equals vs. == String s1 = new String ("abc"); String s2 = новая строка ("abc");

ПРИМЕЧАНИЕ. Строки создаются в пуле констант String, поэтому, когда мы создаем как String s = ”abc”, он проверит пул, вызвав собственный метод intern (), для его существования в существующем пуле, если он это сделал. не найдено ни одной строки, тогда он создаст новую, но если мы вызовем новый оператор, он создаст одну новую строку независимо от проверки существования пула.

  public class StringEqualityTest {
    public static void main(String []a){

    String s1=new String("abc");
    String s2=new String("abc");

     System.out.print("s1.equals(s2)  :"+s1.equals(s2)+"  s1==s2   :");
     System.out.println(s1==s2);

     String s3="abc";
     String s4="abc";

     System.out.print("s3.equals(s4)  :"+s1.equals(s2)+"  s3==s4   :");
     System.out.println(s3==s4);

       }

       }

ВЫВОД: s1.equals (s2): правда s1 == s2: ложь s3.equals (s4): правда s3 == s4: правда

1 голос
/ 09 июня 2009

a == b возвращает истину, если ссылки содержат одно и то же значение, т. Е. Они указывают на один и тот же объект или оба имеют нулевое значение.

Метод equals() может быть переопределен для сравнения объектов. Например, в Strings метод возвращает true, если строки содержат одну и ту же строку, даже если это разные строковые объекты. Вы можете делать подобные вещи со своими объектами.

o.equals() сгенерирует исключение, если o является нулевой ссылкой.

0 голосов
/ 17 октября 2014

== проверяет, указывают ли ссылки на один и тот же объект в памяти

Теперь

, хотя код метода equals в объектном классе - не что иное, как проверка == для ссылок, его можно переопределить, чтобы добавить свои собственные проверки на равенство.

В таких классах, как String, переопределенный метод проверяет правильность строковых литералов или нет. Таким образом, в основном это может использоваться, чтобы проверить, является ли значение тем же или нет.

0 голосов
/ 30 августа 2012

Предположим, у нас есть a и b или два разных объекта, и мы хотим сравнить эти две ссылки на объекты. Затем мы используем оператор == и при использовании a.equals(b) он сравнивает строковые значения.

0 голосов
/ 20 января 2012

==, он возвращает только значение хеш-кода в соответствии с их адресами, поэтому разные адреса, даже если строки или любые другие данные, которые похожи друг на друга, также возвращает false. значение.

0 голосов
/ 03 сентября 2011

== проверяет ссылку на объект, в основном сравнивает хеш-коды. Equals использует содержимое объекта. Помните, мы должны переопределить метод .equals в нашем классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...