09 - Робота з рядками
Опануйте маніпулювання текстом та операції з рядками в Java.
Рядки - один з найпоширеніших типів у Java. Вони необхідні для обробки імен гравців, повідомлень у чаті, описів предметів та всього, що ви бачите.
Основи рядків
Рядки - це об'єкти, що зберігають текст:
String name = "Саймон";
String message = "Ласкаво просимо до Hytale!";
String empty = "";Після створення строку її неможливо змінити. Методи, які, здавалося б, модифікують строку, насправді створюють нову!
String text = "Привіт";
text.toUpperCase(); // Створює "ПРИВІТ", але не зберігає її
System.out.println(text); // Все ще "Привіт"
String upper = text.toUpperCase(); // ✓ Зберегти результат
System.out.println(upper); // "ПРИВІТ"Методи рядків
Довжина
String name = "Анна";
int length = name.length();
System.out.println(length); // 4Зміна регістру
String text = "Привіт світ";
String upper = text.toUpperCase(); // "ПРИВІТ СВІТ"
String lower = text.toLowerCase(); // "привіт світ"Перевірка вмісту
String message = "Ласкаво просимо до Hytale";
boolean hasHytale = message.contains("Hytale"); // true
boolean hasMinecraft = message.contains("Minecraft"); // false
boolean starts = message.startsWith("Ласкаво"); // true
boolean ends = message.endsWith("Hytale"); // trueВитягування частин
String text = "Привіт світ";
char first = text.charAt(0); // 'П'
char last = text.charAt(10); // 'т'
String sub1 = text.substring(0, 6); // "Привіт"
String sub2 = text.substring(7); // "світ"substring(start, end) включає start, але виключає end:
String text = "Hytale";
// 012345 (індекси)
text.substring(0, 2); // "Hy" (індекси 0 і 1)
text.substring(2, 6); // "tale" (індекси 2, 3, 4, 5)
text.substring(2); // "tale" (від 2 до кінця)Заміна тексту
String text = "Я люблю Minecraft";
String replaced = text.replace("Minecraft", "Hytale");
System.out.println(replaced); // "Я люблю Hytale"
String noSpaces = "Привіт Світ".replace(" ", "");
System.out.println(noSpaces); // "ПривітСвіт"Обрізання пробілів
String messy = " Привіт світ ";
String clean = messy.trim();
System.out.println(clean); // "Привіт світ" (без пробілів на початку та в кінці)Розділення рядків
String command = "give player sword 5";
String[] parts = command.split(" ");
System.out.println(parts[0]); // "give"
System.out.println(parts[1]); // "player"
System.out.println(parts[2]); // "sword"
System.out.println(parts[3]); // "5"Порівняння рядків
Завжди використовуйте .equals() для порівняння вмісту рядків!
String name1 = "Стів";
String name2 = "Стів";
// Неправильно - порівнює посилання на об'єкти
if (name1 == name2) {
System.out.println("Те саме");
}
// Правильно - порівнює фактичний текст
if (name1.equals(name2)) {
System.out.println("Те саме");
}
// Ігнорувати регістр при порівнянні
if (name1.equalsIgnoreCase("стів")) {
System.out.println("Те саме (без урахування регістру)");
}Порядок порівняння
String a = "Apple";
String b = "Banana";
int result = a.compareTo(b);
// результат < 0, якщо a йде перед b
// результат == 0, якщо a дорівнює b
// результат > 0, якщо a йде після b
if (a.compareTo(b) < 0) {
System.out.println(a + " йде перед " + b);
}Об'єднання рядків
Використання оператора +
String first = "Привіт";
String second = "світ";
String combined = first + " " + second; // "Привіт світ"
int score = 100;
String message = "Рахунок: " + score; // "Рахунок: 100"Використання concat()
String result = "Привіт".concat(" світ"); // "Привіт світ"Створення довгих рядків
Для багатьох конкатенацій використовуйте StringBuilder:
StringBuilder builder = new StringBuilder();
builder.append("Гравець: ");
builder.append("Анна");
builder.append(", Рівень: ");
builder.append(10);
builder.append(", Здоров'я: ");
builder.append(100);
String result = builder.toString();
System.out.println(result);
// "Гравець: Анна, Рівень: 10, Здоров'я: 100"Звичайне об'єднання створює багато тимчасових рядків:
// Неефективно - створює багато тимчасових рядків
String result = "";
for (int i = 0; i < 1000; i++) {
result = result + i; // Створює 1000 тимчасових рядків!
}
// Ефективно - StringBuilder є змінюваним
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i); // Змінює один об'єкт
}
String result = sb.toString();Використовуйте StringBuilder під час побудови рядків у циклах!
Практичні приклади
Аналіз команди гравця
public class CommandParser {
public static void parseCommand(String command) {
// "/give Steve diamond_sword 1"
String[] parts = command.split(" ");
String action = parts[0].replace("/", ""); // "give"
String player = parts[1]; // "Steve"
String item = parts[2]; // "diamond_sword"
int amount = Integer.parseInt(parts[3]); // 1
System.out.println("Дія: " + action);
System.out.println("Гравець: " + player);
System.out.println("Предмет: " + item);
System.out.println("Кількість: " + amount);
}
public static void main(String[] args) {
parseCommand("/give Steve diamond_sword 1");
}
}Оформлення імені гравця
public class PlayerFormatter {
public static String formatName(String name, int level, String rank) {
StringBuilder formatted = new StringBuilder();
if (rank != null && !rank.isEmpty()) {
formatted.append("[").append(rank).append("] ");
}
formatted.append(name);
formatted.append(" (Рів. ").append(level).append(")");
return formatted.toString();
}
public static void main(String[] args) {
String display1 = formatName("Анна", 10, "VIP");
System.out.println(display1); // "[VIP] Анна (Рів. 10)"
String display2 = formatName("Богдан", 5, null);
System.out.println(display2); // "Богдан (Рів. 5)"
}
}Перевірка імені користувача
public class UsernameValidator {
public static boolean isValid(String username) {
// Правила: 3-16 символів, тільки літери та цифри
if (username == null || username.isEmpty()) {
return false;
}
username = username.trim();
if (username.length() < 3 || username.length() > 16) {
return false;
}
for (int i = 0; i < username.length(); i++) {
char c = username.charAt(i);
if (!Character.isLetterOrDigit(c)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println(isValid("Steve")); // true
System.out.println(isValid("Player_123")); // false (містить підкреслення)
System.out.println(isValid("ab")); // false (занадто коротке)
System.out.println(isValid("")); // false (порожнє)
}
}Конструктор опису предмета
public class ItemDescription {
public static String buildDescription(String name, String rarity,
int damage, int durability) {
StringBuilder desc = new StringBuilder();
// Заголовок з кодом кольору рідкісності
desc.append(getRarityColor(rarity));
desc.append(name);
desc.append("\n");
// Показники
desc.append("Шкода: ").append(damage).append("\n");
desc.append("Міцність: ").append(durability).append("/");
desc.append(durability).append("\n");
desc.append("Рідкісність: ").append(rarity);
return desc.toString();
}
private static String getRarityColor(String rarity) {
switch (rarity.toLowerCase()) {
case "легендарна": return "§6"; // Золотий
case "епічна": return "§5"; // Фіолетовий
case "рідкісна": return "§9"; // Синій
case "звичайна": return "§f"; // Білий
default: return "§7"; // Сірий
}
}
public static void main(String[] args) {
String desc = buildDescription("Екскалібур", "Легендарна", 50, 1000);
System.out.println(desc);
}
}Фільтр повідомлень чату
public class ChatFilter {
private static String[] bannedWords = {"поганеслово1", "поганеслово2"};
public static String filterMessage(String message) {
String filtered = message.toLowerCase();
for (String word : bannedWords) {
if (filtered.contains(word)) {
String replacement = "*".repeat(word.length());
filtered = filtered.replace(word, replacement);
}
}
return filtered;
}
public static void main(String[] args) {
String message = "Це тест поганеслово1";
String clean = filterMessage(message);
System.out.println(clean); // "Це тест ************"
}
}Форматування рядків
Використання String.format()
String name = "Анна";
int level = 10;
double health = 85.5;
String formatted = String.format("%s має рівень %d і %.1f%% здоров'я",
name, level, health);
System.out.println(formatted);
// "Анна має рівень 10 і 85.5% здоров'я"Загальні коди формату:
%s- рядок%d- ціле число%f- число з плаваючою комою%.2f- число з плаваючою комою з 2 десятковими знаками%n- новий рядок (незалежно від платформи)
String.format("Ім'я: %s", "Стів"); // "Ім'я: Стів"
String.format("Рівень: %d", 10); // "Рівень: 10"
String.format("Здоров'я: %.1f", 85.5); // "Здоров'я: 85.5"
String.format("Позиція: (%d, %d, %d)",
10, 64, -5); // "Позиція: (10, 64, -5)"Загальні операції з рядками
Перевірка, чи рядок порожній
String text = "";
// Перевірка на порожній або нульовий
if (text == null || text.isEmpty()) {
System.out.println("Порожній!");
}
// Перевірка на порожній, нульовий або тільки пробіл
if (text == null || text.trim().isEmpty()) {
System.out.println("Порожній або пробіл!");
}Підрахунок входжень
public static int countOccurrences(String text, String target) {
int count = 0;
int index = 0;
while ((index = text.indexOf(target, index)) != -1) {
count++;
index += target.length();
}
return count;
}
// Використання
int count = countOccurrences("привіт привіт світ", "привіт");
System.out.println(count); // 2Зворотний рядок
public static String reverse(String text) {
StringBuilder sb = new StringBuilder(text);
return sb.reverse().toString();
}
// Використання
String reversed = reverse("Привіт");
System.out.println(reversed); // "тівирП"Перевірка на паліндром
public static boolean isPalindrome(String text) {
String cleaned = text.toLowerCase().replaceAll("[^a-z0-9]", "");
String reversed = new StringBuilder(cleaned).reverse().toString();
return cleaned.equals(reversed);
}
// Використання
System.out.println(isPalindrome("racecar")); // true
System.out.println(isPalindrome("hello")); // falseПрактичні вправи
-
Перевірка імені користувача: Напишіть метод, який перевіряє, чи ім'я користувача:
- Складається з 3-16 символів
- Містить тільки літери, цифри та символи підкреслення
- Не починається з цифри
- Повертає true, якщо ім'я є допустимим, і false в іншому випадку
-
Аналізатор команд: Проаналізуйте цей формат команди:
/teleport x y z- Витягніть координати
- Перетворіть їх на цілі числа
- Поверніть масив із трьох значень
-
Форматувальник чату: Створіть метод, який форматує повідомлення в чаті:
- Вхідні дані: ім'я гравця, ранг, повідомлення
- Вихідні дані:
"[RANK] PlayerName: message" - Якщо рангу немає, просто покажіть
"PlayerName: message"
-
Лічильник слів: Порахуйте, скільки слів у реченні (слова розділені пробілами)
-
Великі літери: Перетворіть рядок у форму заголовка:
- Вхідні дані:
"hello world" - Вихідні дані:
"Hello World"
- Вхідні дані: