1. Введение
Строковые значения и операции довольно часто встречаются в повседневной разработке, и любой Java-разработчик должен уметь с ними обращаться.
В этом уроке мы предоставим краткую памятку по общим операциям со строками .
Кроме того, мы прольем свет на различия между equals
и «==», а также между StringUtils#isBlank
и # isEmpty.
2. Преобразование Char в строку
Символ представляет собой один символ
в Java. Но в большинстве случаев нам нужна строка.
Итак, давайте начнем с преобразования char
в String
s :
String toStringWithConcatenation(final char c) {
return String.valueOf(c);
}
3. Добавление строк
Другой часто необходимой операцией является добавление строк с другими значениями, такими как char
:
String appendWithConcatenation(final String prefix, final char c) {
return prefix + c;
}
Мы также можем добавить другие базовые типы с помощью StringBuilder
:
String appendWithStringBuilder(final String prefix, final char c) {
return new StringBuilder(prefix).append(c).toString();
}
4. Получение персонажа по индексу
Если нам нужно извлечь один символ из строки, API предоставляет все, что мы хотим:
char getCharacterByIndex(final String text, final int index) {
return text.charAt(index);
}
Поскольку String
использует char[]
в качестве резервной структуры данных, индекс начинается с нуля .
5. Обработка значений ASCII
Мы можем легко переключаться между char
и его числовым представлением (ASCII) с помощью приведения:
int asciiValue(final char character) {
return (int) character;
}
char fromAsciiValue(final int value) {
Assert.isTrue(value >= 0 && value < 65536, "value is not a valid character");
return (char) value;
}
Конечно, поскольку int
— это 4 байта без знака, а char
— 2 байта без знака, нам нужно убедиться, что мы работаем с допустимыми символьными значениями.
6. Удаление всех пробелов
Иногда нам нужно избавиться от некоторых символов, чаще всего от пробелов. Хороший способ — использовать метод replaceAll
с регулярным выражением :
String removeWhiteSpace(final String text) {
return text.replaceAll("\\s+", "");
}
7. Присоединение коллекций к строке
Другой распространенный случай использования — это когда у нас есть какая-то коллекция
и мы хотим создать из нее строку:
<T> String fromCollection(final Collection<T> collection) {
return collection.stream().map(Objects::toString).collect(Collectors.joining(", "));
}
Обратите внимание, что Collectors.joining
позволяет указывать префикс или суффикс .
8. Разделение строки
Или, с другой стороны, мы можем разделить строку по разделителю с помощью метода split
:
String[] splitByRegExPipe(final String text) {
return text.split("\\|");
}
Опять же, здесь мы используем регулярное выражение, на этот раз для разделения по конвейеру. Поскольку мы хотим использовать специальный символ, мы должны его экранировать .
Другая возможность - использовать класс Pattern :
String[] splitByPatternPipe(final String text) {
return text.split(Pattern.quote("|"));
}
9. Обработка всех символов как потока
В случае детальной обработки мы можем преобразовать строку в IntStream
:
IntStream getStream(final String text) {
return text.chars();
}
10. Равенство ссылок и равенство значений
Хотя строки выглядят как примитивный тип, это не так.
Следовательно, мы должны различать равенство ссылок и равенство значений. Равенство ссылок всегда подразумевает равенство значений, но, как правило, не наоборот. Первое мы проверяем с помощью операции '==', а второе — с помощью метода equals :
@Test
public void whenUsingEquals_thenWeCheckForTheSameValue() {
assertTrue("Values are equal", new String("Test").equals("Test"));
}
@Test
public void whenUsingEqualsSign_thenWeCheckForReferenceEquality() {
assertFalse("References are not equal", new String("Test") == "Test");
}
Обратите внимание, что литералы интернированы в пуле строк . Поэтому компилятор может иногда оптимизировать их для одной и той же ссылки:
@Test
public void whenTheCompileCanBuildUpAString_thenWeGetTheSameReference() {
assertTrue("Literals are concatenated by the compiler", "Test" == "Te"+"st");
}
11. Пустая строка против пустой строки
Между isBlank
и isEmpty
есть небольшая разница .
Строка считается пустой, если она равна нулю
или имеет нулевую длину. Принимая во внимание, что строка пуста, если она равна нулю или содержит только символы пробела:
@Test
public void whenUsingIsEmpty_thenWeCheckForNullorLengthZero() {
assertTrue("null is empty", isEmpty(null));
assertTrue("nothing is empty", isEmpty(""));
assertFalse("whitespace is not empty", isEmpty(" "));
assertFalse("whitespace is not empty", isEmpty("\n"));
assertFalse("whitespace is not empty", isEmpty("\t"));
assertFalse("text is not empty", isEmpty("Anything!"));
}
@Test
public void whenUsingIsBlank_thenWeCheckForNullorOnlyContainingWhitespace() {
assertTrue("null is blank", isBlank(null));
assertTrue("nothing is blank", isBlank(""));
assertTrue("whitespace is blank", isBlank("\t\t \t\n\r"));
assertFalse("test is not blank", isBlank("Anything!"));
}
12. Заключение
Строки являются основным типом во всех видах приложений. В этом руководстве мы изучили некоторые ключевые операции в распространенных сценариях.
Кроме того, мы дали указания на более подробные ссылки.
Наконец, полный код со всеми примерами доступен в нашем репозитории на GitHub .