Строки Java: compareTo() vs. equals()

При тестировании на равенство String в Java я всегда использовал equals(), потому что для меня это, по-видимому, самый естественный метод для него. В конце концов, его имя уже говорит о том, что он намерен делать. Однако недавно мой коллега сказал, что меня учили использовать compareTo() == 0 вместо equals(). Это кажется неестественным (поскольку compareTo() предназначен для обеспечения упорядочения, а не сравнения для равенства) и даже несколько опасного (поскольку compareTo() == 0 не обязательно подразумевает равенство во всех случаях, хотя я знаю, что он делает для String) мне.

Он не знал, почему его учили использовать compareTo() вместо equals() для String, и я тоже не мог найти причину. Это действительно вопрос личного вкуса, или есть ли настоящая причина для любого метода?

Ответ 1

Разница заключается в том, что "foo".equals((String)null) возвращает false, а "foo".compareTo((String)null) == 0 генерирует исключение NullPointerException. Поэтому они не всегда взаимозаменяемы даже для строк.

Ответ 2

При сравнении для равенства вы должны использовать equals(), потому что он четко выражает ваши намерения.

compareTo() имеет дополнительный недостаток, что он работает только с объектами, реализующими интерфейс Comparable.

Это относится, вообще говоря, не только к строкам.

Ответ 3

Два основных отличия заключаются в следующем:

  • equals возьмет любой объект в качестве параметра, но compareTo будет принимать только строки.
  • equals сообщает только, являются ли они равными или нет, но compareTo дает информацию о том, как строки сравниваются лексикографически.

Я взглянул на код класса String, а алгоритм в compareTo и equals выглядит в основном тем же. Я считаю, что его мнение было просто вопросом вкуса, и я согласен с вами - если все, что вам нужно знать, - это равенство строк, а не то, что происходит сначала лексикографически, тогда я бы использовал equals.

Ответ 4

compareTo делает больше работы, если строки имеют разную длину. equals может просто вернуть false, а compareTo должен всегда проверять достаточно символов, чтобы найти порядок сортировки.

Ответ 5

compareTo() применяется не только к строкам, но и к любому другому объекту, потому что compareTo<T> принимает общий аргумент T. String является одним из классов, который реализовал метод compareTo(), реализовав интерфейс Comparable. (compareTo() - метод сопоставимого интерфейса). Таким образом, любой класс свободен для реализации Сопоставимый интерфейс.

Но compareTo() дает упорядочение объектов, обычно используемых при сортировке объектов в порядке возрастания или убывания, тогда как equals() будет говорить только о равенстве и сказать, они равны или нет.

Ответ 6

В контексте строки:
compareTo: сравнивает две строки лексикографически.
equals: сравнивает эту строку с указанным объектом.

compareTo сравнивает две строки по своим символам (при одном и том же индексе) и возвращает целое число (положительное или отрицательное) соответственно.

String s1 = "ab";
String s2 = "ab";
String s3 = "qb";
s1.compareTo(s2); // is 0
s1.compareTo(s3); // is -16
s3.compareTo(s1); // is 16

Ответ 7

equals() должен быть методом выбора в случае OP.

Рассматривая реализацию equals() и compareTo() в java.lang.String по grepcode, мы можем легко видеть, что equals is лучше, если нас просто интересует равенство двух строк:

equals():

 1012  public  boolean равно (Object anObject) {
1013 if ( this == anObject) {
1014 return true;
1015}
1016 if (anObject instanceof String) {
1017 String anotherString = ( String) anObject;
1018 int n = count;
1019 if (n == anotherString.count) {
1020 char v1 [] = va lue;
1021 char v2 [] = anotherString.value;
1022 int я = offset;
1023 int j = anotherString.offset;
1024 while (n--!= 0) {
1025 if (v1 [i ++]!= v2 [j ++])
1026 return false;
1027}
1028 return true;
1029}
1030}
1031 return false;
1032}

и compareTo():

 1174  public  int compareTo ( String anotherString) {
1175 int len1 = count;
1176 int len2 = anotherString.count;
1177 int n = Math. min (len1, len2);
1178 char v1 [] = значение;
1179 char v2 [] = anotherString.value;
1180 int я = offset;
1181 int j = anotherString.offset;
1183 if (i == j) {
1184 int k = i;
1185 int lim = n + i;
1186 , тогда как (k < lim) {
1187 char c1 = v1 [k];
1188 char c2 = v2 [k];
1189 if (c1!= c2) {
1190 return c1 - c2;
1191}
1192 k ++;
1193}
1194} else {
1195 while (n--!= 0) {
1196 char c1 = v1 [i ++];
1197 char c2 = v2 [j ++];
1198 if ( c1!= c2) {
1199 <Б> возвращениеc1 - c2;
1200}
1201}
1202}
1203 return len1 - len2;
1204}

Когда одна из строк является префиксом другого, производительность compareTo() хуже, так как по-прежнему необходимо определить лексикографическое упорядочение, а equals() больше не будет беспокоиться и немедленно вернуть false.

По моему мнению, мы должны использовать эти два, поскольку они были предназначены:

  • equals() для проверки равенства и
  • compareTo(), чтобы найти лексическое упорядочение.

Ответ 8

Похоже, что оба метода в значительной степени выполняют одно и то же, но метод compareTo() принимает строку, а не объект, и добавляет некоторые дополнительные функции поверх обычного метода equals(). Если все, о чем вы заботитесь, это равенство, то метод equals() - лучший выбор, просто потому, что имеет смысл для следующего программиста, который смотрит на ваш код. Разница во времени между двумя различными функциями не должна иметь значения, если вы не зацикливаете какое-то огромное количество предметов. Функция compareTo() действительно полезна, когда вам нужно знать порядок строк в коллекции или когда вам нужно знать разницу в длине между строками, начинающимися с той же последовательности символов.

источник: http://java.sun.com/javase/6/docs/api/java/lang/String.html

Ответ 9

equals() может быть более эффективным, чем compareTo().

Очень важное различие между compareTo и equals:

"myString".compareTo(null);  //Throws java.lang.NullPointerException
"myString".equals(null);     //Returns false

equals() проверяет, совпадают ли два объекта или нет, и возвращает логическое значение.

compareTo() (из интерфейса Comparable) возвращает целое число. Он проверяет, какой из двух объектов "меньше", "равен" или "больше" другого. Не все объекты могут быть логически упорядочены, поэтому метод compareTo() не всегда имеет смысл.

Обратите внимание, что equals() не определяет порядок между объектами, которые выполняет compareTo().

Теперь я советую вам просмотреть исходный код обоих методов, чтобы сделать вывод о том, что equals предпочтительнее, чем compareTo, что связано с некоторыми вычислениями Math.

Ответ 10

Есть определенные вещи, которые вам нужно иметь в виду, переопределяя compareTo в Java, например. Compareto должен быть совместим с равными, а вычитание не должно использоваться для сравнения целочисленных полей, поскольку они могут переполняться. Подробнее о том, что нужно запомнить при переопределении компаратора в Java.

Ответ 11

Равенства могут быть более эффективными, чем сравнение.

Если длина символьных последовательностей в String не соответствует, строки не равны, поэтому отклонение может быть намного быстрее.

Более того, если это тот же объект (равенство идентичности, а не логическое равенство), оно также будет более эффективным.

Если они также реализовали кэширование hashCode, было бы еще быстрее отклонить не равные значения в случае, если их hashCode не соответствует.

Ответ 12

String.equals() требует вызова оператора instanceof, а compareTo() - нет. Мой коллега отметил значительное снижение производительности, вызванное чрезмерным количеством вызовов instanceof в методе equals(), однако мой тест показал, что compareTo() будет только немного быстрее.

Я использовал, однако, Java 1.6. В других версиях (или других поставщиков JDK) разница может быть больше.

Тест сравнивал каждую строку в 1000 массивах элементов, повторяющихся 10 раз.

Ответ 13

  • equals может принимать любой объект как параметр, но compareTo может принимать только String.

  • когда cometo null, compareTo выдаст исключение

  • когда вы хотите узнать, где происходит различие, вы можете использовать compareTo.

Ответ 14

Это эксперимент в некромантии: -)

Большинство ответов сравнивают производительность и различия API. Они пропускают фундаментальную точку, что две операции просто имеют разную семантику.

Ваша интуиция верна. x.equals(y) не является взаимозаменяемым с x.compareTo(y) == 0. Первый сравнивает идентичность, в то время как другой сравнивает понятие "размер". Верно, что во многих случаях, особенно с примитивными типами, эти два совпадающих.

Общий случай таков:

Если x и y одинаковы, они имеют один и тот же "размер": если x.equals(y) истинно = > x.compareTo(y) равно 0.

Однако, если x и y имеют одинаковый размер, это не значит, что они идентичны.

если x.compareTo(y) равно 0, не обязательно означает, что x.equals(y) истинно.

Привлекательный пример, когда идентификатор отличается от размера, будет сложным числом. Предположим, что сравнение производится по их абсолютной величине. Поэтому заданы два комплексных числа: Z1 = a1 + b1 * я и Z2 = a2 + b2 * i:

Z1.equals(z2) возвращает true тогда и только тогда, когда a1 = a2 и b1 = b2.

Однако Z1.compareTo(Z2) возвращает 0 для и бесконечное число пар (a1, b1) и (a2, b2), если они удовлетворяют условию a1 ^ 2 + b1 ^ 2 == a2 ^ 2 + b2 ^ 2.

Ответ 15

  • equals:  необходимых для проверки равенства и ограничения дубликатов. Многие классы библиотеки Java используют это, если они хотят найти дубликаты. например HashSet.add(ob1) будет добавляться только в том случае, если этого не существует. Поэтому, если вы расширяете некоторые классы, подобные этому, переопределите equals().

  • compareTo:     требуется для упорядочивания элемента. Опять для стабильной сортировки вам требуется равенство, поэтому возвращается 0.

Ответ 16

Равные значения -

1- Переопределить метод GetHashCode, чтобы позволить типу работать корректно в хеш-таблице.

2 Не бросайте исключение в реализацию метода Equals. Вместо этого верните false для нулевого аргумента.

3 -

  x.Equals(x) returns true.

  x.Equals(y) returns the same value as y.Equals(x).

  (x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true.

Последовательные вызовы x.Equals(y) возвращают одно и то же значение, если объект, на который ссылаются x и y, не изменяется.

x.Equals(null) returns false.

4- Для некоторых видов объектов желательно иметь Equals-тест для равенства значений вместо ссылочного равенства. Такие реализации Equals возвращают true, если оба объекта имеют одинаковое значение, даже если они не являются одним и тем же экземпляром.

Пример -

   Object obj1 = new Object();
   Object obj2 = new Object();
   Console.WriteLine(obj1.Equals(obj2));
   obj1 = obj2; 
   Console.WriteLine(obj1.Equals(obj2)); 

Выход: -

False
True

а compareTo -

Сравнивает текущий экземпляр с другим объектом того же типа и возвращает целое число, указывающее, предшествует ли текущий экземпляр, следует или происходит в той же позиции в порядке сортировки, что и другой объект.

Он возвращает -

Меньше нуля - этот экземпляр предшествует obj в порядке сортировки. Zero - этот экземпляр встречается в той же позиции в порядке сортировки, что и obj. Больше нуля - этот экземпляр следует obj в порядке сортировки.

Он может вызывать ArgumentException, если объект не является тем же типом, что и экземпляр.

Например, вы можете посетить здесь.

Поэтому я предлагаю лучше использовать Equals вместо compareTo.

Ответ 17

"равно" сравнивать объекты и возвращать true или false и "сравнивать с" return 0, если true или число [ > 0] или [< 0], если false вот пример:

<!-- language: lang-java -->
//Objects Integer
Integer num1 = 1;
Integer num2 = 1;
//equal
System.out.println(num1.equals(num2));
System.out.println(num1.compareTo(num2));
//New Value
num2 = 3;//set value
//diferent
System.out.println(num1.equals(num2));
System.out.println(num1.compareTo(num2));

Результаты:

num1.equals(num2) =true
num1.compareTo(num2) =0
num1.equals(num2) =false
num1.compareTo(num2) =-1

Документация Сравнить с: https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

Документация Равно: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

Ответ 18

equals() проверяет, равны ли две строки или нет. Он дает логическое значение. compareTo() проверяет, равен ли строковый объект, больше или меньше, другому объекту string.It дает результат как: 1, если строковый объект больше 0, если оба они равны -1, если строка меньше другой строки

э:

String a = "Amit";
String b = "Sumit";
String c = new String("Amit");
System.out.println(a.equals(c));//true
System.out.println(a.compareTo(c)); //0
System.out.println(a.compareTo(b)); //1