JavaRush /Java блог /Random UA /Клас String
articles
15 рівень

Клас String

Стаття з групи Random UA
  • Методи
  • Генеруємо випадковий рядок
  • Порівняння рядків: equals()чи ==?
Клас Stringчасто використовується програмістами, тому його слід вивчити дуже добре. Клас String - 1Слід пам'ятати, що об'єкти класу Stringє незмінними. Тому, коли вам здається, що ви змінюєте рядок, то насправді ви створюєте новий рядок. У Java є спеціальні класи StringBufferі StringBuilder, які допускають зміни в рядку. Класи String, StringBuffer, StringBuilderвизначені в пакеті java.lang та доступні автоматично без оголошення імпорту. Усі три класи реалізують інтерфейс CharSequence. Створити рядок дуже просто. Наприклад, можна так:
String aboutCat = "Кот - это звучит гордо, а если наступить на хвост, то громко";
Можна створити масив рядків:
String[] cats = {"Васька", "Барсик", "Мурзик"};
Можна створити порожній об'єкт класу String:
String str = new String();
Можна створити рядок через масив символів:
char[] chars = { 'c', 'a', 't' };
String str = new String(chars);
Є ще конструктор, що дозволяє встановити діапазон символьного масиву. Вам потрібно вказати початок діапазону та кількість символів для використання:
char[] chars = {'c', 'a', 't', 'a', 'm', 'a', 'r', 'a', 'n' };
String str = new String(chars, 0, 3);
Можна створити об'єкт класу Stringз об'єкта класів StringBufferта StringBuilderза допомогою наступних конструкторів:
String(StringBuffer об'єкт_StrBuf)
String(StringBuilder об'єкт_StrBuild)

Оператори +та += дляString

Мовою Java знак плюс ( +) означає конкатенацію рядків (concatenation), іншими словами - об'єднання рядків.
String cat = "Кот";
String name = "Васька";
//складываем две строки и пробел между ними, чтобы слова не слиплись
String fullname = cat + " " + name; // получится Кот Васька
Якщо один з операндів у виразі містить рядок, інші операнди також повинні бути рядками. Тому Java сама може привести змінні до рядкового уявлення, навіть якщо вони не є рядками.
int digit = 4;
String paws = " лапы";
String aboutcat = digit + paws; // хотя мы складываем число и строку, но все равно получим строку
За кулисами Java за нас преобразовало число 4 в строку "4"

Форматування рядків

Припустимо, у нас є рядковий ресурс:
<string name="aboutcat">У кота по имени Барсик четыре лапы, один хвост. Ему 5 лет</string>
Щоб вивести цей рядок програмно в елементі TextView, можна використовувати код:
TextView tvCatsInfo = (TextView)findViewById(R.id.textView1);
tvCatsInfo.setText(R.string.aboutcat);
Уявіть, що у вас кілька котів. Можна, звичайно, завести для кожного кота свій рядок. Але ж рядки дуже схожі, змінюються лише імена та вік. Також можна змінювати кількість лап та хвостів (що ви курите?). У таких випадках можна застосувати форматування рядків. Потрібно визначити слова, які ми змінюватимемо і замінити їх на спеціальний набір символів, які починаються з символу відсотка, потім йде число, що збільшується на одиницю, далі для рядків $sабо $dчисел. Отже, змінимо наш рядковий ресурс так:
<string name="aboutcat">У кота по имени %1$s %2$s лапы, %3$s хвост. Ему %4$d лет</string>
Внесемо зміни до коду:
String strBarsik = "Барсик";
String strPaws = "четыре";
String strTail = "один";
int year = 5;
String strCats = getResources().getString(R.string.aboutcat);
String strFinal = String.format(strCats, strBarsik, strPaws, strTail, year);
tvCatsInfo.setText(strFinal);
Якщо вас є кіт Васька та йому шість років, то додаємо дві змінні та форматуємо рядок
String strVaska = "Васька";
year = 6;
String strFinal = String.format(strCats, strVaska, strPaws, strTail, year);
tvCatsInfo.setText(strFinal);
Тут показаний найпростіший приклад із форматуванням. Пам'ятайте про нього та застосовуйте у потрібних місцях.

Рядковий ресурс

Рядки бажано зберігати в ресурсах. Програмно доступ до рядкового ресурсу робиться так:
String catName = getResources().getString(R.string.barsik);

Витягти рядки з рядкових масивів у ресурсах

Припустимо, у вас є рядковий масив, визначений у файлі strings.xml під назвою cats_array. Тоді отримати доступ до рядків із ресурсів можна так:
Resources res = getResources();
String[] cats = res.getStringArray(R.array.cats_array);

Методи

public char charAt (int index) Повертає символ із зазначеним усуненням у цьому рядку. Відлік йде від 0. Не треба використовувати негативні та неіснуючі значення, будьте серйознішими. Використовуйте , щоб вийняти кілька символів getChars().
String testString = "Котёнок";
char myChar = testString.charAt(2);
tv.setText(Character.toString(myChar)); // выводит третий символ - т
public int codePointAt(int index) Повертає Unicode-символ у заданому індексі
String testString = "Котёнок";
int myChar = testString.codePointAt(3);
tv.setText(String.valueOf(myChar)); // возвращает 1105
public int codePointBefore(int index) Повертає Unicode-символ, який передує цьому індексу
String testString = "Котёнок";
int myChar = testString.codePointBefore(4);
tv.setText(String.valueOf(myChar)); // возвращает 1105
public int codePointCount(int start, int end) Обчислює кількість Unicode-символів між позиціями startтаend
String testString = "Котёнок";
int myChar = testString.codePointCount(0, 3);
tv.setText(String.valueOf(myChar)); // возвращает 3
public int compareTo(String string) Порівнює вказаний рядок, використовуючи значення символів Unicode і обчислює, який із рядків менше, дорівнює або більше наступного. Може використовуватись при сортуванні. Регістр враховується. Якщо рядки збігаються, то повертається 0, якщо менше нуля, то рядок, що викликає, менше рядка string, якщо більше нуля, то рядок, що викликає рядок більше string. Слова з великим регістром стоять вище за слово з нижнім регістром.
String testString = "Котёнок";

if (testString.compareTo("котёнок") == 0) {
    tvInfo.setText("Строки равны");
} else {
    tvInfo.setText("Строки не равны. Возвращено"
            + testString.compareTo("котёнок")); // возвращает -32
}
Відсортуємо масив рядків через бульбашкове сортування.
String[] poem = { "Мы", "везём", "с", "собой", "кота" };

for (int j = 0; j < poem.length; j++) {
	for (int i = j + 1; i < poem.length; i++) {
		if (poem[i].compareTo(poem[j]) < 0) {
			String temp = poem[j];
			poem[j] = poem[i];
			poem[i] = temp;
		}
	}
	System.out.println(poem[j]);
}
В результаті ми отримаємо:
Мы
везём
кота
с
собой
Як бачите, від зміни місць доданків сума сортування коти не змінюється. public int compareToIgnoreCase (String string) Порівнює вказаний рядок, використовуючи значення символів Unicode, без урахування регістру.
String testString = "Котёнок";

if (testString.compareToIgnoreCase("котёнок") == 0) {
    tv.setText("Строки равны"); // слова одинаковы, если не учитывать регистр
} else {
    tv.setText("Строки не равны. Возвращено"
            + testString.compareTo("котёнок"));
}
public String concat (String string) Поєднує рядок із зазначеним рядком. Повертається новий рядок, який містить об'єднання двох рядків. Зверніть увагу, що саме ім'я методу містить кота!
String testString = "Сук";
String newString = testString.concat("кот");
tv.setText(newString);
Метод виконує таку ж функцію, як і оператор +і можна було написати Сук + кот. Але справжній кошатник використовуватиме "котячий" метод. public boolean contains (CharSequence cs) Визначає, чи містить рядок послідовність символів уCharSequence
String testString = "котёнок";

if(testString.contains("кот")){
    infoTextView.setText("В слове котёнок содержится слово кот!");
}
public static String copyValueOf (char[] data, int start, int length) Створює новий рядок, що містить зазначені символи з масиву, Dataпочинаючи з позиції start(нумерація починається з нуля) довгою length . public static String copyValueOf(char[] data) Створює новий рядок, що містить символи із зазначеного масиву. Зміна масиву після створення рядка не змінює створений рядок. public boolean endsWith(String suffix) Перевіряє, чи рядок закінчується символами suffix.
String str1 = "Суккот";

if(str1.endsWith("кот"))
    infoTextView.setText("Слово заканчивается на котике");
else
    infoTextView.setText("Плохое слово. Нет смысла его использовать");
public boolean equals (Object string) Порівнює зазначений об'єкт і рядок і повертає true якщо порівнювані рядки рівні, тобто. містить самі символи й у порядку з урахуванням регістру.
String str1 = "Кот";
String str2 = "Кошка";

if(str1.equals(str2))
    infoTextView.setText("Строки совпадают");
else
    infoTextView.setText("Строки не совпадают");
Не плутати метод з оператором ==, який порівнює два посилання на об'єкти і визначає, чи посилаються вони на той самий екземпляр. Дивись пункт Порівняння рядків: equals()чи ==? public boolean equalsIgnoreCase(String string) Порівнює вказаний рядок з вихідним рядком без урахування регістру і повертає true якщо вони рівні. Діапазон AZ вважається рівним діапазону az.
String str1 = "Кот";
String str2 = "кот";

if(str1.equalsIgnoreCase(str2))
    infoTextView.setText("Строки совпадают");
else
    infoTextView.setText("Строки не совпадают");
public static String format(Locale locale, String format, Object... args)
Повертає відформатований рядок, використовуючи формат і аргументи, що додається, локалізованих в даній області. Наприклад, дату або час
// выводим число типа float с двумя знаками после запятой
String.format("%.2f", floatValue);
Склеюємо два слова, які виводяться з нового рядка. При цьому друге слово виводиться у верхньому регістрі.
String str1 = "Кот";
String str2 = "васька";
String strResult = String.format("%s\n%S", str1, str2);
// выводим результат в TextView
infoTextView.setText(strResult);
Конвертуємо число у вісімкову систему.
String str1 = "8";
int inInt = Integer.parseInt(str1); // конвертируем строку в число
String strResult = String.format("(Восьмеричное значення): %o\n", inInt);

infoTextView.setText(strResult);
За аналогією виводимо у шістнадцятковій системі
String str1 = "255";
int inInt = Integer.parseInt(str1);
String strResult = String.format("(Шестнадцатеричное значення): %x\n", inInt);
// число 255 будет выведено як ff
infoTextView.setText(strResult);
Для верхнього регістру використовуйте %X, тоді замість ffбуде FF. Для десяткової системи використовуйте %d. Дату теж можна виводити по-різному.
Date now = new Date();
Locale locale = Locale.getDefault();
infoTextView.setText(
		String.format(locale, "%tD\n", now) + // (MM/DD/YY)
		String.format(locale, "%tF\n", now) + // (YYYY-MM-DD)
		String.format(locale, "%tr\n", now) + // Full 12-hour time
		String.format(locale, "%tz\n", now) + // Time zone GMT offset
		String.format(locale, "%tZ\n", now)); // Localized time zone bbreviation
public byte[] getBytes(String charsetName) Повертає відформатований рядок, використовуючи формат, що додається. public void getBytes(int start, int end, byte[] data, int index)та інші перевантажені версії Метод зберігає символи в масив байтів, альтернатива методу getChars(). Часто використовується при експорті рядків із різних джерел, де використовуються інші символи Unicode. Наприклад, Java за замовчуванням працює з 16-бітовими символами Unicode, а в інтернеті часто рядки використовують 8-бітовий код Unicode, ASCII та ін. public void getChars(int start, int end, char[] buffer, int index) Метод для вилучення кількох символів з рядка. Вам треба вказати індекс початку підрядка ( start), індекс символу, що настає за кінцем підрядки (end). Масив, який приймає виділені символи, знаходиться в параметрі buffer . Індекс у масиві, починаючи з якого буде записуватися підрядок, передається в параметріindex . Слідкуйте, щоб масив був достатнього розміру, щоб у ньому помістабося всі символи зазначеного підрядка.
String unusualCat = "Котёнок по имени Гав";
int start = 5;
int end = 12;
char[] buf = new char[end - start];
unusualCat.getChars(start, end, buf, 0);
infoTextView.setText(new String(buf));
public int hashCode() Повертає ціле число — хеш для даного об'єкта. public int indexOf(int c) Повертає номер першої зустрічної позиції із зазначеним індексом с.
String testString = "котёнок";
// символ ё встречается в четвёртой позиции (index = 3)
infoTextView.setText(String.valueOf(testString.indexOf("ё")));
public int indexOf (int c, int start) Шукає індекс з, починаючи з позиціїstart
String testString = "котёнок";
// вернёт -1, так як после 5 символа буквы ё нет
infoTextView.setText(String.valueOf(testString.indexOf("ё", 4)));
public int indexOf (String string) Шукає ланцюжок символівsubString
String testString = "У окошка";
infoTextView.setText(String.valueOf(testString.indexOf("кошка")));
public int indexOf (String subString, int start) Шукає ланцюжок символів subString, починаючи з позиціїstart
String testString = "У окошка";
infoTextView.setText(String.valueOf(testString.indexOf("кошка", 2)));
public String intern () "Xешує" рядок public boolean isEmpty () Перевіряє, чи є рядок порожнім
if(catname.isEmpty()) {
    // здесь ваш код
}
Цей метод з'явився в API 9 (Android 2.1). Для старих пристроїв використовуйте String.length() == 0 public int lastIndexOf (String string) и другие перегруженные версии Повертає номер останньої зустрічної позиції із зазначеним індексом. Наприклад, отримати ім'я файлу без розширення можна так:
filename.toString().substring(0, filename.getString().lastIndexOf("."));
У цьому прикладі ми отримуємо позицію останньої точки і отримуємо підряд до неї. public int length() Повертає довжину рядка
String testString = "котёнок";
infoTextView.setText(String.valueOf(testString.length())); // возвращает 7 (семь символов)
public boolean matches(String regularExpression) Перевіряє, чи рядок відповідає регулярним виразам.
public int offsetByCodePoints (int index, int codePointOffset)
Повертає позицію, розташовану на відстані codePointOffsetпісля початкової позиції, задану параметром index public boolean regionMatches (int thisStart, String string, int start, int length) Метод порівнює вказану частину рядка з іншою частиною рядка. Потрібно задати індекс початку діапазон рядка об'єкта класу, що викликає String. Рядок для порівняння передається у параметрі string. Індекс символу, починаючи з якого потрібно виконувати порівняння, передається в параметрі start, а довжина підстроки, що порівнюється в параметрі length. public boolean regionMatches (boolean ignoreCase, int thisStart, String string, int start, int length) Перевантажена версія. Метод порівнює вказану частину рядка з іншою частиною рядка, ігноруючи регістр. public String replace(CharSequence target, CharSequence replacement) и другие перегруженные версии Змінює символ або послідовність символів targetнаreplacement
String testString = "кит";
// меняем и на о
infoTextView.setText(testString.replace("і", "о")); // возвращается кот
public String replaceAll (String regularExpression, String replacement) public String replaceFirst (String regularExpression, String replacement) Видаляє перші символи за допомогою регулярного виразу. Наприклад, якщо потрібно видалити нулі на початку чисел 001, 007, 000024, можна використовувати такий виклик.
String s = "001234-cat";
String s = s.replaceFirst ("^0*", ""); // останется 1234-cat
public String[] split (String regularExpression) и другие перегруженные версии Розбиває рядок на масив із слів. Наприклад, є рядок Васька Рижик Мурзик Барсик і ми хочемо отримати масив імен котів:
String catnames = "Васька Рыжик Мурзик Барсик";
String aCats[] = catnames.split(" ");  // по пробелу
Отримаємо:
aCats[0] = Васька
aCats[1] = Рыжик
aCats[2] = Мурзик
aCats[3] = Барсик
public boolean startsWith(String prefix) Перевіряє, чи починається рядок символами prefixз початку рядка
String str1 = "котлета";

if(str1.startsWith("кот"))
    infoTextView.setText("Слово содержит кота");
else
    infoTextView.setText("Плохое слово. Нет смысла его использовать");
public boolean startsWith(String prefix, int start) Перевіряє, чи починається заданий рядок символами prefixіз зазначеної позиції.
String str1 = "Суккот";

if(str1.startsWith("кот", 3))
    infoTextView.setText("Слово содержит кота");
else
    infoTextView.setText("Плохое слово. Нет смысла его использовать");
public CharSequence subSequence (int start, int end) Аналогічний методу substring(), але може використовуватися для CharSequence. public String substring(int start)та інші перевантажені версії Створює нову послідовність/рядок із символами з цього рядка, починаючи з позиції startдо кінця рядка/закінчуючи символом з позиції end. Новий рядок містить символи до startend - 1, тому беремо на один символ більше.
String testString = "скотина";

infoTextView.setText(testString.substring(1, 4)); // возвращается кот
public char[] toCharArray() Копіює символи в цьому рядку масив символів. Той самий результат можна отримати через метод getChars(). Документація не рекомендує використовувати цей метод, пропонуючи метод charAt().
String unusualCat = "Котёнок по имени Гав";

char[] yomoe = unusualCat.toCharArray();
infoTextView.setText(String.valueOf(yomoe[3]));
public String toLowerCase() и другие перегруженные версии Перетворює рядок на нижній регістр. Перетворенням керує задану за промовчанням регіональну мову. String cat = "Кіт"; String lower = cat.toLowerCase(); infoTextView.setText(lower); public String toString () Повертає рядок. Для самого рядка, який сам уже є рядком, повертати рядок безглуздо (про, як я загнув). Але насправді цей метод є дуже корисним для інших класів. public String toUpperCase() Перетворює рядок у верхній регістр. Перетворенням керує задану за промовчанням регіональну мову.
String cat = "Кот";
String upper = cat.toUpperCase();
infoTextView.setText(upper);
public String trim() Видаляє пробіли на початку та в кінці рядка.
String str = "   Hello Kitty  ".trim();
infoTextView.setText(str);
public static String valueOf(long value)та інші перевантажені версії Конвертує вміст (числа, об'єкти, символи, масиви символів) у рядок.
int catAge = 7; // это число

infoTextView.setText(String.valueOf(catAge)); // преобразовано в строку

Генеруємо випадковий рядок

Припустимо, нам потрібний випадковий рядок із заданих символів.
private static final String mCHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
private static final int STR_LENGTH = 9; // длина генерируемой строки
Random random = new Random();

public void onClick(View view) {
    TextView infoTextView = (TextView) findViewById(R.id.textViewInfo);
    infoTextView.setText(createRandomString());
}

public String createRandomString() {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < STR_LENGTH; i++) {
        int number = random.nextInt(mCHAR.length());
        char ch = mCHAR.charAt(number);
        builder.append(ch);
    }
    return builder.toString();
}

Порівняння рядків: equals()чи ==?

Розглянемо приклад.
String str1 = "Мурзик";
String str2 = new String(str1);
boolean isCat = str1 == str2;

infoTextView.setText(str1 + " == " + str2 + " -> " + isCat);
Хоча у двох змінних міститься одне й те саме слово, ми маємо справу з двома різними об'єктами і оператор ==поверне false . Якось, коли дерева були великими, мені знадобилося порівняти два рядки з різних джерел. Хоча рядки виглядали однаково, порівняння за допомогою оператора ==повертало false і плутало мені всі карти. І лише потім я дізнався, що потрібно використовувати метод equals(). Рядок у Java - це окремий об'єкт, який може не збігатися з іншим об'єктом, хоча на екрані результат рядка, що виводиться, може виглядати однаково. Просто Java у випадку з логічним оператором ==(а також !=) порівнює посилання на об'єкти (при роботі з примітивами такої проблеми немає):
String s1 = "hello";
String s2 = "hello";
String s3 = s1;
String s4 = "h" + "e" + "l" + "l" + "o";
String s5 = new String("hello");
String s6 = new String(new char[]{'h', 'e', 'l', 'l', 'o'});

infoTextView.setText(s1 + " == " + s2 + ": " + (s1 == s2));
// попробуйте и другие варианты
// infoTextView.setText(s1 + " equals " + s2 + ": " + (s1.equals(s2)));
// infoTextView.setText(s1 + " == " + s3 + ": " + (s1 == s3));
// infoTextView.setText(s1 + " equals " + s3 + ": " + (s1.equals(s3)));
// infoTextView.setText(s1 + " == " + s4 + ": " + (s1 == s4));
// infoTextView.setText(s1 + " equals " + s4 + ": " + (s1.equals(s4)));
// infoTextView.setText(s1 + " == " + s5 + ": " + (s1 == s5)); // false
// infoTextView.setText(s1 + " equals " + s5 + ": " + (s1.equals(s5)));
// infoTextView.setText(s1 + " == " + s6 + ": " + (s1 == s6)); // false
// infoTextView.setText(s1 + " equals " + s6 + ": " + (s1.equals(s6)));
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ