1. Знайомство зі StringUtils

StringUtils – клас Apache Commons, який використовується найчастіше. Він містить різні утиліти та методи, які допомагають розробникам уникати написання шаблонного або просто громіздкого коду для базових операцій.

Багато методів у класі StringUtils мають свої еквіваленти в java.lang.String, але на відміну від методів java.lang.String є безпечними для роботи з null. Це означає, що виняток NullPointerException не викидається в несподівану мить.

Apache Commons містить низку методів, тож давай розглянемо деякі з найпопулярніших.

Список методів StringUtils:

isEmpty() Перевіряє, чи рядок порожній
equals() Порівнює рядки
compare() Порівнює рядки
indexOf() Пошук підрядка у рядку
lastIndexOf() Пошук підрядка у рядку
contains() Перевіряє входження підрядка в рядок
containsIgnoreCase() Перевіряє входження підрядка в рядок, ігноруючи регістр
containsAny() Перевіряє входження підрядка в будь-якому місці рядка
containsNone() Перевіряє, чи немає входження підрядка в будь-якому місці рядка
containsOnly() Перевіряє входження підрядка в рядок
substring() Отримання підрядка
split() Розбиваємо рядок на підрядки
join() Об'єднуємо підрядки
remove() Видаляємо підрядок
replace() Замінити підрядок
countMatches() Вважаємо кількість збігів

2. StringUtils.isEmpty() та StringUtils.isBlank()

Обидва методи використовуються для перевірки того, чи містить рядок текст. Вони повертають true, якщо рядок справді порожній. isBlank() також поверне true, якщо рядок містить лише пробіли.

Вони також мають зворотні методи: isNotEmpty() та isNotBlank().

Давай подивимося, як ти можеш використовувати isEmpty() разом з його аналогом java.lang.String.isEmpty(), а також isBlank():


String nullValue = null;
String emptyValue = "";
String blankValue = "\n \t   \n";

if(StringUtils.isEmpty(emptyValue)) {
   System.out.println("emptyValue is emptyValue");
}

if(StringUtils.isBlank(blankValue)) {
   System.out.println("blankValue is blankValue");
}

if(!nullValue.isEmpty()) {
   System.out.println("nullString isn't null");
}

Тут три змінних типу String. Одна вказує на null, друга не є null, але не має вмісту (порожній рядок), а третя – не порожня, але на друку видасть порожній результат.

Виконання цього коду призводить до:

emptyValue is emptyValue
blankValue is blankValue
Exception in thread "main" java.lang.NullPointerException

Метод isEmpty(), який вбудовано в java.lang.String, небезпечний для null. Ти легко отримаєш NullPointerException, якщо спробуєш перевірити, чи він порожній, оскільки викличеш метод за посиланням null. Потрібно буде заздалегідь перевірити, чи є посилання нульовим:


String nullValue = null;
String emptyValue = "";
String blankValue = "\n \t   \n";

if(StringUtils.isEmpty(emptyValue)) {
   System.out.println("emptyValue is emptyValue");
}

if(StringUtils.isBlank(blankValue)) {
   System.out.println("blankValue is blankValue");
}

if(nullValue != null && !nullValue.isEmpty()) {
   System.out.println("nullString isn't null");
}

Тепер це призводить до:

emptyValue is emptyValue
blankValue is blankValue

І якщо ми протестуємо ці методи на nullString:


String nullValue = null;

if(StringUtils.isEmpty(nullValue)) {
   System.out.println("nullValue is emptyValue");
}

if(StringUtils.isBlank(nullValue)) {
   System.out.println("nullValue is blankValue");
}

То отримаємо:

nullValue is emptyValue
nullValue is blankValue

Методи StringUtils безпечні для null і дають очікуваний результат, навіть якщо вони передали null.

3. StringUtils.equals()

Цей метод порівнює два рядки і повертає true, якщо вони ідентичні, або обидва посилання вказують на null. Але май на увазі, що цей метод чутливий до регістру.

Давай подивимося, як він працює:


System.out.println(StringUtils.equals(null, null));
System.out.println(StringUtils.equals(null, "якась інформація"));
System.out.println(StringUtils.equals("якась інформація", null));
System.out.println(StringUtils.equals("якась інформація",  "якась інформація"));
System.out.println(StringUtils.equals("якась додаткова інформація", "якась інформація"));

Результат:

true
false
false
true
false

Для порівняння методу equals() зі StringUtils з java.lang.String.equals():


String nullValue = null;

System.out.println(StringUtils.equals(nullValue, null));
System.out.println(StringUtils.equals(nullValue, "какая-то информация"));

System.out.println(nullValue.equals(null));
System.out.println(nullValue.equals("какая-то информация"));

Це знову привело тебе до:

true
false
Exception in thread "main" java.lang.NullPointerException

Знову ж таки, виклик методу для посилання null призводить до виключення NullPointerException, і потрібно буде заздалегідь перевірити, чи є змінна null перед її використанням.

4. StringUtils.compare()

Оголошення цього методу виглядає так:


public static int compare(final String str1, final String str2)

Цей метод порівнює два рядки лексикографічно, як це робить метод java.lang.String.compareTo(), і повертає:

  • 0, якщо str1 дорівнює str2 (або обидва рівні null)
  • Значення менше, ніж 0, якщо str1 менше, ніж str2
  • Значення більше, ніж 0, якщо str1 більше, ніж str2

Лексикографічний порядок – це порядок за словником. Давай подивимося, як ми можемо використовувати це у нашій програмі:


System.out.println(StringUtils.compare(null, null));
System.out.println(StringUtils.compare(null , "javaRush"));
System.out.println(StringUtils.compare("javaRush", null));
System.out.println(StringUtils.compare("javaRush", "JAVARUSH"));
System.out.println(StringUtils.compare("javaRush", "javaRush"));

Отримуємо:

0
-1
1
32
0

Примітка: значення null вважається меншим, ніж значення, відмінне від null. Два значення null вважаються рівними.

5. Перевіряємо, чи містить рядок інший підрядок

Для цього у StringUtils є 5 методів:

  • contains()
  • containsIgnoreCase()
  • containsAny()
  • containsNone()
  • containsOnly()

Метод contains() повертає true чи false залежно від того, чи міститься послідовність пошуку у інший послідовності чи ні.

Якщо до такого методу передати null, він поверне false. Якщо передати не null, то метод просто викличе java.lang.String.indexOf(String str) в об'єкта, що передається.

Приклади:


String value = "JavaRush is cool";

System.out.println(StringUtils.contains(null, "a"));
System.out.println(StringUtils.contains(value, "JavaRush"));
System.out.println(StringUtils.contains(value, "C++"));
System.out.println(StringUtils.contains(value, "javarush"));

Метод чутливий до регістру, тому останній виклик також поверне:

false
true
false
false

Метод containsAny() повертає true, якщо рядок, що передався першим аргументом, містить хоча б один із підрядків, що передався 2-N аргументами.

Приклад:


String value = "JavaRush is cool";
System.out.println(StringUtils.containsAny(value, "cool", "c00l", "bro", "hello"));

Виведе на екран:

true

Цей метод також чутливий до регістру.

Метод containsNone()

Коли потрібно перевірити, що певний рядок не містить нічого зі списку, можна скористатися методом containsNone(). Першим параметром до нього передається рядок, а наступні параметри – це рядки, яких не має бути в цільовому стоку.

Приклад:


String s = "JavaRush is cool";
System.out.println(StringUtils.containsNone(s, 'g', 'a'));

Виведення в консолі:

false

6. Робота з підрядками

Робота з підрядками схожа на роботу методів класу String:


substring(String str, int start)
substring (String str, int start, int end)

Ці методи повертають підрядок з рядка str. Рядок відзначається двома індексами: start і end. Як заведено в Java, останній символ діапазону – end-1. У чому перевага цих методів?

Якщо передати в такий метод null, він просто поверне null, а не кине виняток. Ці методи підтримують від'ємні значення індексів. Водночас рядок розглядається як замкнута петля. Після останнього символу йде перший, тощо.

Давай подивимося, як ми можемо його використати:


System.out.println(StringUtils.substring("lets java", 2, 6));
System.out.println(StringUtils.substring("lets java", -8));
System.out.println(StringUtils.substring(null, 3));

Виконання наведеного вище коду дає нам:

ts j
ets java
null

StringUtils.split()

Метод, який дозволяє розбити рядок на підрядки за допомогою спеціального роздільника. Якщо такий є в цільовому рядку, метод поверне масив підрядків. Якщо символу немає – повернеться порожній масив. Ну а якщо в метод передати null, він поверне null. Давай розглянемо цей код та роботу методу:


String myData = "Address, City, State, Zip, Phone, Email, Password";

System.out.println(Arrays.toString(StringUtils.split(myData, ',')));
System.out.println(Arrays.toString(StringUtils.split(null, '.')));
System.out.println(Arrays.toString(StringUtils.split("", '.')));

Результат:

[Address,  City,  State,  Zip,  Phone,  Email,  Password]
null
[]

StringUtils.join()

Метод join() дозволяє склеїти масив рядків в один рядок. До того ж, в нього можна передати спеціальний символ-розділювач, який додасться між підрядками в результуючому рядку. Якщо ж метод передати null, він поверне null.

Цей метод є прямою протилежністю методу split(). Давай розглянемо цей простий приклад:


String myData = "Address, City, State, Zip, Phone, Email, Password";

String[] myString =  StringUtils.split(myData, ',');
System.out.println(StringUtils.join(myString, '-'));

Виконання наведеного вище коду дає нам:

Address- City- State- Zip- Phone- Email- Password

StringUtils.replace()

Шукає рядок усередині рядка, знаходить його, якщо він існує, і замінює всі його входження на новий рядок.

Оголошення цього методу виглядає так:

public static String replace(final String text, final String searchString, final String replacement)

Якщо рядок пошуку не знайдено в тексті, нічого не станеться: текст залишиться тим самим. За такою ж логікою, якщо текст дорівнює null, цей метод повертає null. Якщо ти шукаєш null-рядок або замінюєш підрядок на null, метод поверне оригінальний рядок.

Давай спробуємо цей метод:


String value = "JavaRush is the best";
System.out.println(StringUtils.replace(value, "best", "cool"));

Результат:

JavaRush is the cool