Автор оригинала: Olivera Popović.
Вступление
Проще говоря, Строка
используется для хранения текста, т. е. последовательности символов. Наиболее часто используемым классом Java, без сомнения, является класс String
, и при таком высоком использовании разработчикам Java необходимо тщательно ознакомиться с классом и его общими операциями.
Строка
О String
можно многое сказать, начиная с способов их инициализации и заканчивая пулом строковых литералов , однако в этой статье мы сосредоточимся на общих операциях, а не на самом классе.
Хотя, если вы хотите узнать больше о различных способах создания строк в Java, вам следует проверить String vs StringBuilder vs StringBuffer .
Здесь мы предполагаем, что вы знакомы с тем фактом , что String
являются неизменяемыми , поскольку это очень важно знать, прежде чем обращаться с ними. Если нет, обратитесь к ранее связанной статье, где это подробно описано.
Класс String
содержит множество вспомогательных методов, которые помогают нам обрабатывать наши текстовые данные:
- Определить Длину Строки
- Поиск символов и подстрок
- Сравнение Строк
- Извлечение Подстрок
- Изменение Регистра Строки
- Удаление Пробелов
- Форматирование Строк
- Регулярное выражение и проверка подстрок
- Замена символов и подстрок
- Разделение и соединение строк
- Создание Массивов Символов
- Равенство Строк
Объединение строк
Прежде чем мы начнем использовать любой из этих методов для строк, мы должны взглянуть на объединение строк, поскольку это довольно распространенная вещь. Давайте начнем с оператора +
. Класс String
перегружает этот оператор, и он используется для объединения двух строк:
String aplusb = "a" + "b"; // The operands can be String object reference variables as well String a = "a"; String b = "b"; aplusb = a + b;
Оператор +
работает очень медленно. String
объекты неизменяемы, поэтому каждый раз, когда мы хотим объединить n строк, Java должна копировать символы из всех строк в новый String
объект. Это дает нам квадратичную (O(n^2)) сложность.
Это не проблема с небольшими строками или когда мы объединяем сразу несколько строк одновременно ( Строка + "b" + "c" + "d";
). Java автоматически использует StringBuilder
для объединения нескольких строк одновременно, поэтому источником потери производительности является объединение в циклы. Обычно для чего-то подобного мы использовали бы вышеупомянутый класс StringBuilder
.
Он работает как изменяемый |/Строка объект. Это обходит все копирование в конкатенации строк и дает нам линейную
(O(n)) сложность.
int n = 1000; // Not a good idea! Gives the right result, but performs poorly. String result = ""; for (int i = 0; i < n; i++) { result += Integer.valueOf(i); } // Better, performance-friendly version. StringBuilder sb = new StringBuilder(""); for (int i = 0; i < n; i++) { sb.append(i); }
Мы также можем объединить данные с помощью метода concat()
:
String str1 = "Hello"; System.out.println(str1.concat("World"));
Выход:
Hello World
Примечание : При использовании конкатенации строк с другими типами данных они неявно преобразуются в их строковое представление:
System.out.println("2 = " + 2);
Это дает ожидаемый результат”.
System.out.println("2 = " + 1 + 1);
В обычных обстоятельствах, 1+1
сначала будет оцениваться, поскольку Java обрабатывает операции справа налево. Однако на этот раз этого не произойдет – выход есть”. Это происходит из-за так называемого “приоритета оператора”.
По сути, когда встречаются два или более оператора ” + ” (при отсутствии других операторов или скобок), Java начнет с крайнего левого оператора “+” и продолжит оттуда. Если бы мы хотели, чтобы результат снова был”, нам нужно было бы добавить круглые скобки в соответствующем месте.
System.out.println("2 = " + (1 + 1));
С другой стороны, если мы попытаемся использовать метод concat()
с другим типом данных:
String str1 = "Hello"; System.out.println(str1.concat(53));
Нас встретили бы с исключением:
incompatible types: int cannot be converted to String
При использовании операнда +
Java автоматически преобразует тип данных в строку, тогда как при использовании метода concat ()
этого не происходит.
Кстати, со всеми методами, которые мы рассмотрим в этой статье, нам не нужно указывать ссылочную переменную, иногда для краткости проще просто использовать их в литерале:
// Instead of this... String ourString = "this is just some string"; System.out.println(ourString.substring(5,10)); // ...we can do this: System.out.println("this is just some string".substring(5,10));
На самом деле, любой из способов хорош, но второй способ дает меньше кода.
Определить Длину Строки
length()
возвращает общее количество символов в нашей строке
.
isEmpty()
возвращает true
или false
в зависимости от того, является ли наша Строка
пустой или нет. Таким образом, это означает, что isEmpty()
возвращает true
для того же случая, что length()
возвращает 0.
Например:
if (s.length() == 0) // or s.isEmpty() { System.out.println("s is empty"); } else System.out.println("s isn't empty, it's: " + s + "\n");
Здесь мы покажем, как вы можете использовать эти методы для проверки наличия пустой строки. Условная проверка также может быть заменена на s.is Пустой()
и будет работать точно так же.
Поиск символов и подстрок
Поскольку Строка
является неизменяемой последовательностью символов, мы можем спросить, какой символ находится в какой позиции, или найти позицию символа. Индексирование Строки
начинается с 0, как мы привыкли с массивами.
charAt(индекс int)
возвращает значение символа по заданному индексу.
indexOf()
перегружен и, следовательно, имеет несколько применений:
indexOf(int ch)
возвращает первую позицию индекса, соответствующую заданному значению символаindexOf(int ch, int fromIndex)
возвращает первый индекс, соответствующий заданному значению символа ПОСЛЕfromIndex
indexOf(строковая подстрока)
возвращает (первую) начальную позициюподстроки
вСтроке
объекте, для которого она была вызванаindexOf(строковая подстрока, int fromIndex)
такой же, как и в предыдущем методе, но поиск начинается сfromIndex
вместо 0
Все перегруженные indexOf()
методы возвращают -1 если индекс не был найден.
lastIndexOf()
также перегружен и имеет сигнатуры метода, эквивалентные indexOf()
, а также возвращает -1, если соответствующий индекс не был найден. Он выполняет поиск объекта String
в обратном направлении, если не указан fromIndex
.
Индекс, передаваемый методу, должен находиться в диапазоне [0, пример.длина() - 1]
должна быть действительной. В противном случае будет выдано исключение StringIndexOutOfBoundsException
.
String example = "This should be complicated enough to show some things we should show"; // Find the characters at the indexes given System.out.println(example.charAt(0)); System.out.println(example.charAt(5)); // An StringIndexOutOfBoundsException is thrown in both these cases: // System.out.println(example.charAt(-1)); // System.out.println(example.charAt(200)); // Find the index of characters or substrings System.out.println(example.indexOf('s')); // returns the first occurence of 's' System.out.println(example.indexOf('s', 4)); // the first 's' after index 4 System.out.println(example.indexOf("should")); // the index of the first "should" in our string System.out.println(example.indexOf("should", 15)); // the index of the first "should" in our // string _after_ index 15 // Find the last index of characters or substrings System.out.println(example.lastIndexOf('s')); // returns the first occurence of 's' when we look backwards from the end of the string System.out.println(example.lastIndexOf('s', 45)); // searches for 's' backwards from the position 45 System.out.println(example.lastIndexOf("should")); // returns the position at which the substring 'should' appears, looking backwards from the end of the string System.out.println(example.lastIndexOf("should", 20)); // finds substring 'should' from position 20 backwards, and returns the position at which it begins
Это приведет к следующему:
T s 3 5 5 57 64 42 57 5
Примечание : indexOf(int ch, int fromIndex)
часто используется в циклах, когда мы хотим что-то сделать для каждого вхождения символа в строке
.
int foundAt = -1; String example = "This should be complicated enough to show some things we should show"; while (true) { foundAt = example.indexOf('s', foundAt + 1); if (foundAt == -1) break; else { // do something with that information } }
Сравнение Строк
Метод compareTo()
лексикографически сравнивает нашу Строку
с другой. Фактическое сравнение двух строк основано на значении Юникода каждого символа в строке. Метод возвращает либо положительное число, либо отрицательное число, либо 0.
Если бы все символы в нашей строке были строчными (или прописными) буквами, возвращаемое значение метода compareTo()
можно было бы интерпретировать как “если бы возвращаемое значение было отрицательным, моя строка стояла бы перед другой строкой в словаре”.
Я подчеркиваю тот момент, что буквы должны быть в одном и том же случае, так как в противном случае функция может выдать неожиданный результат.
Метод compareTo()
не просматривает все символы в наших строках, он возвращается, как только достигает конца любой из строк или как только находит несоответствующий символ. В этом случае функция возвращает (значение в Юникоде несоответствующего символа в нашей строке) – (Значение в Юникоде несоответствующего символа в данной строке) .
Для всех, кому интересно – ASCII является частью Unicode. Это означает, что a-z и A-Z находятся в том же порядке, что и в кодировке ASCII, то есть все они следуют друг за другом в соответствующих случаях. А именно, az коды районов между 97-122 и А-Я есть 65-90 . Таким образом, значение для ” a “равно 97, значение для “b” равно 98 и так далее. Таким образом, когда мы вычитаем значение Юникода для ” b ” из “a”, мы получим -1. Это означает, что ” а “- это одна буква перед “в”, как оно и есть.
System.out.println("a".compareTo("a")); System.out.println("a".compareTo("b")); System.out.println("1".compareTo("12345678")); System.out.println("2".compareTo("12345678")); System.out.println("abcd".compareTo("abgggggggggg"));
0 -1 -7 1 -4
В третьей строке приведенного выше кода в данном случае compareTo
возвращает разницу в длине строки, поскольку он не нашел несоответствующего символа до того, как в одной строке “закончились” символы.
И в последней строке мы видим , что -4 печатается из – за " c " - "g"
, так как это первое обнаруженное несоответствие, и ему плевать на остальное.
Примечание : “Неожиданная” часть при использовании compareTo()
возникает, когда мы сравниваем строки с разными случаями.
System.out.println("ORANGE".compareTo("apple"));
Мы могли бы ожидать, что метод вернет положительное значение, так как “яблоко” должно стоять перед “АПЕЛЬСИНОМ”. Однако значение Юникода для ” O “меньше, чем значение Юникода для “a”.
Иногда это может быть предпочтительным поведением, но в противном случае мы используем compareToIgnoreCase()
. Этот метод делает по существу то же самое , что и по сравнению с ()
, он просто делает вид, что все в одном и том же случае, и дает нам “правильный” порядок словаря.
Примечание : compareTo()
и compareToIgnoreCase()
часто используются, когда мы создаем Компаратор
для пользовательского класса.
Например, предположим, что у нас есть Человек
объект, подобный следующему:
class Person { String firstName; String lastName; // ... }
Теперь предположим, что у нас есть ArrayList
под названием “люди” из многих Человек
объектов, в произвольном порядке. Мы хотели бы отсортировать этот ArrayList
так, чтобы они были упорядочены в лексикографическом порядке на основе их фамилии, и если у людей одна и та же фамилия, мы хотели бы отсортировать их по имени.
ComparatorpersonComparator = new Comparator () { @Override public int compare(Person p1, Person p2) { if (p1.firstName.compareTo(p2.firstName) != 0) { return p1.firstName.compareTo(p2.firstName); } else return p1.lastName.compareTo(p2.lastName); } }; Collections.sort(people, personComparator);
Извлечение Подстрок
“Подстрока” – это подмножество (или часть) другой строки. Метод substring()
возвращает новую строку, которая является подстрокой строки, на которой мы используем метод.
Другими словами, если бы нам нужна была новая строка, содержащая первые три символа нашей строки, мы бы использовали yourstring.substring(0, 3)
.
Метод substring()
имеет два варианта:
подстрока(int startIndex)
возвращаетСтроку
, содержащую все символы изstartIndex
(включительно) до конца нашейСтроки
. Он ведет себя так же, какподстрока(int startIndex, наша строка.длина())
.подстрока(int startIndex, int endIndex)
возвращаетСтроку
, содержащую все символы отstartIndex
(включительно) доendIndex
(эксклюзивно, т. е. символ вendIndex
не возвращается)
Примечание : Заданные индексы все еще должны находиться в интервале [0, outstring.длина()-1]
. Java, в отличие от некоторых других языков, НЕ поддерживает отрицательные индексы в методе substring ()
! Java вызовет исключение StringIndexOutOfBoundsException
по любой из следующих причин:
startIndex
отрицательныйendIndex
больше длины нашегоСтроки
объектаНачальный индекс
больше, чемКонечный индекс
Хотя в документации явно не говорится, что “отрицательные значения вообще не допускаются” (можно иметь привычку указывать -1 в качестве endIndex
из других языков программирования), это правило может быть выведено из того факта, что startIndex
не может быть отрицательным, и что endIndex
должен быть больше, чем startIndex
.
Однако Java просто заставляет нас сделать дополнительный шаг по написанию нашей строки.длина() - то же число
, что и endIndex
вместо просто - Некоторое число
.
String ourString = "abcdef"; System.out.println(ourString.substring(0,3)); System.out.println(ourString.substring(2)); System.out.println(ourString.substring(1,3)); // If we want the last few characters System.out.println(ourString.substring(ourString.length()-3));
abc cdef bc def
Изменение Регистра Строки
Эти два простых метода используются для изменения регистра символов в строке.
toLowerCase()
: изменяет все прописные символы на строчные (игнорирует все остальное)Прописные буквы()
: изменяет все символы нижнего регистра на прописные (игнорирует все остальное)
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
String ourString = "ThInK oF a ClEvEr StRiNg"; System.out.println(ourString.toLowerCase()); System.out.println(ourString.toUpperCase()); System.out.println(ourString);
Это приведет к следующему:
think of a clever string THINK OF A CLEVER STRING ThInK oF a ClEvEr StRiNg
Обратите внимание, что сам начальный String
объект не изменился.
Удаление Пробелов
Этот метод возвращает копию исходного объекта String
, в котором удалены все начальные и конечные пробелы (пробелы, вкладки, новые строки).
String ourString = " Any non-leading and non-trailing whitespace is \n preserved "; System.out.println(ourString.trim());
Выход:
Any non-leading and non-trailing whitespace is preserved
Функция trim()
часто используется при обработке пользовательского ввода, так как она гарантирует, что у нас нет бесполезных пробелов, и не изменяет строку, если мы этого не сделаем.
Очень распространенным использованием trim()
при вводе пользователем является проверка того, были ли вообще введены какие-либо символы, не являющиеся пробелами:
// Usually we check for empty inputs like this: if (userinput.isEmpty()) { ... } // ...or the equivalent if (userinput.length() != 0) { ... } // But a better way to check would be this, which // handles cases where the user entered only // whitespace (i.e. " ") if (userinput.trim().isEmpty()) { ... }
Форматирование Строк
Метод format()
возвращает отформатированную строку с заданным форматом и аргументами. Он используется для упрощения жизни при форматировании сложных строк в Java. Он работает аналогично printf
в C:
public static String format(String form, Object... args)
Это объявление метода может показаться сложным, но давайте рассмотрим его поближе:
- Для наших целей часть
static
означает, что этот метод вызывается через классString
, а не через объект классаString
. Это означает, что когда мы хотим использовать этот метод, мы должны написатьString.format (...)
, а ненаш String.format(...)
. Мы можем вызвать метод вторым способом, новаша строка
в любом случае не будет играть никакой роли в методе. - В
...
(три точки) послеОбъекта
просто говорит, что здесь может быть передано переменное число аргументов. Один, два или пятьдесят, все зависит отСтроковой формы
.
Давайте начнем с простого примера.
int a = 2; int b = 3; int c = 4; int d = 1; // %d indicates we want to print an integer System.out.println(String.format("%d", a));
2
Метод format()
проходит через строку form
, ищет специальные символы и заменяет их аргументами в args
.
Специальные символы начинаются с %
. В нашем примере мы использовали %d
, который Java понимает как “Я попытаюсь проанализировать предоставленный аргумент в args
как целое число”.
Немного более проницательный пример того, когда format()
полезен:
// Very messy, hard to read, and hard to maintain System.out.println("a = " + a + "\n" + "b = " + b + "\n" + "c = " + c + "\n" + "d = " + d + "\n"); // Much prettier System.out.println(String.format("a = %d \nb = %d \nc = %d \nd = %d", a, b, c, d));
Как мы видим в этом примере, Java сопоставляет специальные символы, начинающиеся с %
, с аргументами по порядку. Это означает , что когда он увидит первый %d
, он сопоставит его с a
, вторым %d
с b
и так далее.
Существует множество специальных символов для формат ()
, и вы можете найти полный список в документах (включая целую кучу параметров даты/времени), но наиболее часто вы будете видеть и использовать следующие:
%d
: целочисленные типы (байт, короткий, int, длинный, BigInteger)%s
: Строки%f
: дляс плавающей запятой
в виде десятичного числа,%e
отформатировано как десятичное число в компьютерной научной нотации, и%g
печатает либо то же самое, что%f
или%e
в зависимости от значения точности после округления.%b
: длялогических
значений. Если значение равноnull
, выводится “false”
Вообще говоря, метод format()
имеет, казалось бы, сложный синтаксис:
%[argument_index$][flags][width][.precision]conversion
argument_index
, флаги
, ширина
и точность
являются необязательными , как указано в []
.
Точность может означать разные вещи для разных типов данных. Для поплавков/двойников точность имеет очевидное значение “сколько цифр я должен показать после десятичного периода”. Кроме того, точность определяет максимальное количество символов, которые должны быть записаны в выходные данные.
double ourDouble = 1123.9303; System.out.println(String.format("%f", ourDouble)); System.out.println(String.format("%.3f", ourDouble)); // specifies that we only want 3 digits after decimal point System.out.println(String.format("%e", ourDouble)); String ourString = "what does precision do with strings?"; System.out.println(String.format("%.8s", ourString)); // prints the first 8 characters of our string int ourInt = 123456789; // System.out.println(String.format("%.4d", ourInt)); // precision can't be used on ints
Это выведет:
1123.930300 1123.930 1.123930e+03 what doe
Необязательный параметр width
указывает минимальную ширину вывода.
// If our number has less than 6 digits, this will // add extra 0s to the beginning until it does System.out.println(String.format("%06d", 12)); // If our number has more than 6 digits, it will just print it out System.out.println(String.format("%06d", 1234567)); // We can specify output width, with the output being aligned // to the right if it's shorter than the given space. If it's // longer, everything gets printed. The || are added for // demonstration purposes only System.out.println(String.format("|%20d|", 12)); // Or we can align the output to the left System.out.println(String.format("|%-20d|", 12)); // We can also easily print an octal/hexadecimal value of an integer System.out.println(String.format("Octal: %o, Hex: %x", 10, 10));
Выполнение этого кода приведет к следующему:
000012 1234567 | 12| |12 | Octal: 12, Hex: a
Регулярное выражение и проверка подстрок
содержит(последовательность символов)
возвращает истину
, если s
является частью нашего String
объекта ( s
может быть Строкой
самой по себе или StringBuilder
объектом или действительно чем-либо, что реализует Последовательность символов
), в противном случае он возвращает ложь
.
StartsWith(префикс строки)
возвращает true
, если наш String
объект буквально начинается с заданного префикса
, в противном случае он возвращает false
.
EndsWith(суффикс строки)
возвращает true
, если наш String
объект буквально заканчивается данным суффиксом
, в противном случае он возвращает false
.
соответствует(регулярное выражение строки)
возвращает true
, если вся наша Строка
соответствует заданному регулярному выражению .
Все эти методы довольно прямолинейны. Хотя соответствует()
предполагает знание регулярных выражений.
String ourString = "This string contains a contains."; System.out.println(ourString.contains("contains")); System.out.println(ourString.startsWith("T")); System.out.println(ourString.endsWith(":)")); System.out.println(ourString.matches(".*string.*"));
Эти операции выводят следующее:
true true false true
Замена символов и подстрок
заменить(char oldChar, char newChar)
заменяет все вхождения oldChar
на newChar
.
заменить(цель последовательности символов, замена последовательности символов)
заменяет все вхождения целевой
строки на замену
строки (это означает, что мы можем заменить целые подстроки вместо просто символов).
replaceAll(регулярное выражение строки, замена строки)
заменяет все подстроки, соответствующие аргументу regex
, строкой replacement
.
replaceFirst(регулярное выражение строки, замена строки)
заменяет только первую подстроку, соответствующую аргументу regex
, строкой replacement
.
Чтобы избежать путаницы, replace()
также заменяет ВСЕ вхождения последовательности символов, хотя существует метод с именем replaceAll()
. Разница в том, что replaceAll()
и replaceFirst()
используют регулярное выражение для поиска последовательностей символов, которые необходимо заменить.
String ourString = "We really don't like the letter e here"; System.out.println(ourString.replace('e', 'a')); System.out.println(ourString.replace("here", "there")); System.out.println(ourString.replaceAll("e(r+)", "a")); System.out.println(ourString.replaceFirst("e(r+)", "a"));
Wa raally don't lika tha lattar a hara We really don't like the letter e there We really don't like the letta e hae We really don't like the letta e here, only the first occurrence was replaced
Разделение и соединение строк
Методы split()
и join()
являются двумя сторонами одной медали.
split(регулярное выражение строки)
разбивает эту строку с помощью заданного регулярного выражения и возвращает массив символов.
разделение(регулярное выражение строки, ограничение int)
аналогично предыдущему методу, но разбивает только ограничение
количество раз.
присоединиться(разделитель последовательности символов, последовательность символов... элементы)
с другой стороны, возвращает Строку
, содержащую все перечисленные элементы
, соединенные разделителем
.
присоединиться(разделитель последовательности символов, повторяемый расширяет последовательность символов> элементы)
это очень сложный способ сказать, что мы можем использовать join()
в таких вещах, как списки, для объединения всех элементов в Строку
с использованием заданного разделителя
. расширяет последовательность символов> элементы)
String ourString = "apples, oranges, pears, pineapples"; String[] fruits = ourString.split(","); System.out.println(Arrays.toString(fruits)); // This is a great place to use the aforementioned trim() method // to remove the space at the beginning of some of the words for(int i = 0; i < fruits.length; i++) { fruits[i] = fruits[i].trim(); } System.out.println(Arrays.toString(fruits)); // Arrays.toString() formats the output array on its own
[apples, oranges, pears, pineapples] [apples, oranges, pears, pineapples]
Имейте в виду, что split()
принимает регулярное выражение, чтобы решить, где разделить строку, поэтому будьте осторожны при использовании символов, которые имеют особое значение в регулярных выражениях.
Поскольку эти символы являются общими (особой проблемой является”.”, поскольку это означает “любой символ” в регулярном выражении), безопасным способом использования split()
является Pattern.quote (".")
, который гарантирует, что ничто не понимается как специальный символ регулярного выражения.
String ourString = "apples.oranges.pears.pineapples"; // This returns then prints an empty array, since every // character is interpreted as something to be split at // and ignored System.out.println(Arrays.toString(ourString.split("."))); // The "regex safe" way of doing this would be System.out.println(Arrays.toString(ourString.split(Pattern.quote(".")))); // Splits our string to two substrings at most, // completely ignoring all other occurrences of "." System.out.println(Arrays.toString(ourString.split(Pattern.quote("."), 2)));
[] [apples, oranges, pears, pineapples] [apples, oranges.pears.pineapples]
join()
делает прямо противоположное split()
. Мы используем join ()
, когда у нас есть массив/список/и т. Д. Строк (или Stringbuilder
/ Строковые буферы
), которые мы хотим сформировать в одну новую Строку
с использованием некоторого (или без) разделителя.
// A common use is to avoid repetitive concatenation, // i.e. "1" + "," + "2" + "," + "3" + "," + "4" System.out.println(String.join(",", "1", "2", "3", "4")); // We can pass an array or any class that implements // Iterable (containing character sequences) as the // second parameter as well String arrayOfStrings[] = {"1","2","3","4","5"}; System.out.println(String.join("-", arrayOfStrings)); System.out.println(String.join("-", Arrays.asList(arrayOfStrings))); // Works just fine with lists as well // Join them with an empty string to convert an array // of Strings to one single String without any extra data System.out.println(String.join("", arrayOfStrings));
1,2,3,4 1-2-3-4-5 1-2-3-4-5 12345
Создание Массивов Символов
Этот метод преобразует строку
, на которой она используется, в массив символов. Он возвращает новый массив символов, содержащий все символы (по порядку), которые находятся в строке |.
toCharArray()
простая сигнатура метода.
String ourString = "These will all become separate characters"; System.out.println(Arrays.toString(ourString.toCharArray()));
Это приведет к распечатке следующего:
[T, h, e, s, e, , w, i, l, l, , a, l, l, , b, e, c, o, m, e, , s, e, p, a, r, a, t, e, , c, h, a, r, a, c, t, e, r, s]
Равенство Строк
равно(объект str)
сравнивает две строки и возвращает true
, если строки содержат одинаковые символы в одном и том же порядке, и false
в противном случае. Сравнение чувствительно к регистру (используйте equalsIgnoreCase()
для сравнения без учета регистра).
Важно понимать, что равно()
и ==
выполняют две разные операции. равно()
сравнивает символы внутри Строки
объекта, как упоминалось ранее, в то время как ==
сравнивает равенство ссылок на объекты, чтобы увидеть, ссылаются ли они на один и тот же экземпляр. В то время как такие утверждения, как 1
вернет значение true "строка"
может и не вернуться.
Сложность здесь в том, что вывод ==
зависит от того, как мы инициализировали Строку
объекты, которые мы сравниваем:
String s1 = "Just a String"; String s2 = "Just a String"; System.out.println(s1 == s2); System.out.println(s1.equals(s2)); s2 = new String("Just a String"); System.out.println(s1 == s2); System.out.println(s1.equals(s2));
true true false true
функция equals()
возвращает true
в обоих случаях. Поэтому вам всегда следует использовать equals ()
, если вы действительно не хотите проверить, ссылаются ли две ссылочные переменные на один и тот же экземпляр, хотя это довольно редко.
Вывод
Важно понимать нюансы строк и строковых методов в Java. Тонкие, труднодоступные ошибки могут возникать с такими вещами, как split()
и регулярное выражение специальных символов, или при ошибочном использовании ==
, когда мы хотели использовать equals()
.
Лучше всего всегда смотреть на то, как работает метод, проверять их на себе, чтобы помнить о вещах, на которые вам нужно обратить внимание. Кроме того, знание того, какие методы имеются в вашем распоряжении, избавляет вас от ненужной работы по самостоятельному внедрению уже имеющихся методов.