String.equals: примеры (JAVA)

Сравнение строк методом equals в Java
Раздел: Строки (String) - поиск и сравнение
String.equals(Object anObject): boolean

Что делает метод String.equals

Метод String.equals(Object) в Java сравнивает содержимое двух строк по символьным значениям. Это переопределённый метод из Object, имеющий сигнатуру public boolean equals(Object anObject). Метод возвращает true, если аргумент не равен null, принадлежит типу String и содержит те же последовательности символов в том же порядке. В противном случае возвращается false.

Ключевые особенности:

  • Сравнение чувствительно к регистру; символы должны точно совпадать.
  • Первой проверяется ссылка на тот же объект (быстрая оптимизация).
  • Далее проверяется длина строки; при неравенстве длин возвращается false.
  • Построчное сравнение символов выполняется оптимизированно; сложность примерно O(n), где n - длина строки при совпадении.
  • Метод финальный для класса String, поведение стабильно между версиями Java.

Аргументы и возвращаемое значение:

  • Аргумент: Object anObject. Может быть любым объектом. Если это не String, результат будет false.
  • Возвращаемое значение: boolean. true - строки содержат одинаковую последовательность символов, false - иначе.

Дополнительные замечания: метод не выполняет нормализацию Unicode; две визуально эквивалентные строки могут быть не равны, если их кодовые точки отличаются. Для безопасного сравнения с возможным null рекомендуется использовать Objects.equals(a, b) или сравнивать литерал с переменной ("const".equals(var)), чтобы избежать NullPointerException.

Короткие примеры использования

Несколько простых примеров с кодом и ожидаемым выводом.

// Пример 1: простое сравнение
String a = "hello";
String b = new String("hello");
System.out.println(a.equals(b));
true
// Пример 2: сравнение с учётом регистра
String s1 = "Hello";
String s2 = "hello";
System.out.println(s1.equals(s2));
System.out.println(s1.equalsIgnoreCase(s2));
false
true
// Пример 3: сравнение с null (вызов на null вызывает NPE)
String x = null;
String y = "test";
// следующая строка выбросит NullPointerException
// System.out.println(x.equals(y));
// безопасный вариант
System.out.println(java.util.Objects.equals(x, y));
false
// Пример 4: сравнение с другим типом
String s = "123";
Object o = Integer.valueOf(123);
System.out.println(s.equals(o));
false

Похожие методы в Java и их особенности

  • equalsIgnoreCase(String) - сравнение, игнорирующее регистр; полезно при проверке без учёта регистра, но не учитывает локаль-специфические правила объединения символов.
  • contentEquals(CharSequence) - сравнивает строку с любым CharSequence (например, StringBuilder), подходит для сравнения с буферными типами.
  • regionMatches(...) - сравнение подстрок с возможностью игнорирования регистра и задания диапазонов; используется для частичных совпадений.
  • compareTo(String) и compareToIgnoreCase(String) - лексикографическое сравнение, возвращают отрицательное, ноль или положительное число; подходят, когда нужен порядок, а не только равенство.
  • Objects.equals(a, b) - безопасное сравнение, учитывающее null, удобно при возможных нулевых значениях.
  • Библиотечные утилиты (например, org.apache.commons.lang3.StringUtils.equals) добавляют удобство и дополнительные проверки.

Аналоги в других языках и отличия

Краткие примеры и особенности поведения в популярных языках.

PHP

// Сравнение строк
<?
$a = "a";
$b = "a";
var_dump($a === $b); // строгое сравнение
bool(true)

JavaScript

// В JS строка сравнивается оператором ===
let a = 'Hello';
let b = 'Hello';
console.log(a === b);
true

Python

# В Python используется == для сравнения содержимого
a = 'hi'
b = 'hi'
print(a == b)
True

SQL

-- В SQL используется = для точного совпадения, LIKE для шаблонов
SELECT 'match' WHERE 'abc' = 'abc';
match

C#

// В C# оператор == для string сравнивает содержимое
string s1 = "x";
string s2 = new string(new char[]{'x'});
Console.WriteLine(s1 == s2);
Console.WriteLine(string.Equals(s1, s2, StringComparison.Ordinal));
True
True

Kotlin

// В Kotlin оператор == вызывает equals
val a = "k"
val b = "k"
println(a == b)
println(a === b) // проверка ссылочной идентичности
true
false

Go

// В Go строки сравниваются оператором == по содержимому
package main
import "fmt"
func main(){
    a := "go"
    b := "go"
    fmt.Println(a == b)
}
true

Lua

-- В Lua сравнение == для строк по содержимому
print("a" == "a")
true

Отличия от Java: в большинстве языков операция сравнения строк встроена и часто безопасна для null-подобных значений, но нюансы с учётом локали и нормализации остаются. В C# и Kotlin есть явные варианты для ссылочного сравнения. В Java следует помнить об особенностях null и о возможности использования методов, игнорирующих регистр.

Типичные ошибки при использовании String.equals

  • Использование оператора == вместо equals, что сравнивает ссылки, а не содержимое.
  • Вызов equals на null, приводящий к NullPointerException.
  • Ожидание нечувствительности к регистру от equals; в таких случаях нужен equalsIgnoreCase или преобразование регистра.
  • Игнорирование нормализации Unicode: визуально одинаковые символы могут иметь разные кодовые точки.
  • Сравнение с объектами другого типа - всегда false, иногда это приводит к логическим ошибкам.

Примеры.

// Ошибка 1: == вместо equals
String a = new String("x");
String b = new String("x");
System.out.println(a == b); // часто false
System.out.println(a.equals(b)); // true
false
true
// Ошибка 2: вызов на null
String n = null;
// следующая строка выбросит исключение
// System.out.println(n.equals("x"));
// Безопасный приём: литерал слева или Objects.equals
System.out.println("x".equals(n));
System.out.println(java.util.Objects.equals(n, "x"));
false
false
// Ошибка 3: Unicode-эквивалентность
String s1 = "\u00E9"; // é (Latin-1)
String s2 = "e\u0301"; // e + ́ (e + combining acute)
System.out.println(s1.equals(s2));
// Для корректного сравнения требуется нормализация
String ns1 = java.text.Normalizer.normalize(s1, java.text.Normalizer.Form.NFC);
String ns2 = java.text.Normalizer.normalize(s2, java.text.Normalizer.Form.NFC);
System.out.println(ns1.equals(ns2));
false
true

Изменения и заметки по версиям Java

Сигнатура и поведение String.equals(Object) не менялись в последних релизах Java. Метод остаётся финальным и гарантирует сравнение содержимого. Изменения внутренней реализации класса String (например, компактные строки в Java 9) не влияют на семантику equals. Рекомендации по безопасности при работе с null и по нормализации Unicode остаются актуальными.

Расширенные и нечастые примеры использования

Продвинутые приёмы сравнения строк с учётом локали, производительности и типов.

Пример java
// Пример: сравнение содержимого StringBuilder с помощью contentEquals
String s = "abc";
StringBuilder sb = new StringBuilder();
sb.append('a').append('b').append('c');
System.out.println(s.contentEquals(sb));
true
Пример java
// Пример: частичное сравнение с regionMatches
String text = "HelloWorld";
// сравнить подстроку "World" с позиции 5
System.out.println(text.regionMatches(5, "World", 0, 5));
// с игнорированием регистра
System.out.println(text.regionMatches(true, 0, "hello", 0, 5));
true
true
Пример java
// Пример: сравнение с учётом локали через Collator (для лексикографии с локалью)
import java.text.Collator;
import java.util.Locale;
Collator coll = Collator.getInstance(new Locale("tr")); // турецкий
String A = "I";
String B = "ı"; // точка/без точки различаются в турецком
System.out.println(coll.compare(A, B));
(значение может быть отрицательным, нулём или положительным в зависимости от локали)
Пример java
// Пример: нормализация Unicode перед сравнением
String s1 = "\u00E9"; // é
String s2 = "e\u0301"; // e + ́
boolean raw = s1.equals(s2);
boolean norm = java.text.Normalizer.normalize(s1, java.text.Normalizer.Form.NFC)
               .equals(java.text.Normalizer.normalize(s2, java.text.Normalizer.Form.NFC));
System.out.println(raw + " / " + norm);
false / true
Пример java
// Пример: использование equals в коллекциях с HashSet
java.util.Set set = new java.util.HashSet<>();
set.add("one");
System.out.println(set.contains(new String("one"))); // relies on equals + hashCode
true
Пример java
// Пример: безопасное сравнение в Stream при возможных null
java.util.List list = java.util.Arrays.asList("a", null, "c");
long count = list.stream().filter(x -> java.util.Objects.equals(x, "a")).count();
System.out.println(count);
1
Пример java
// Пример: производительность - быстрый отказ по длине уже реализован в equals
String long1 = "x".repeat(1000000) + "a";
String long2 = "x".repeat(1000000) + "b";
// equals быстро обнаружит различие в конце, но сначала сравнит длину
System.out.println(long1.length() == long2.length());
System.out.println(long1.equals(long2));
true
false

джава String.equals function comments

En
String.equals Compares this string to the specified object