← Назад к вопросам

Капитализация первых букв слов в строке

1.3 Junior🔥 111 комментариев
#Другое#Основы Java

Условие

Напишите функцию, которая принимает строку и возвращает её с каждым словом, начинающимся с заглавной буквы.

Примеры

  • "hello world" → "Hello World"
  • "java programming language" → "Java Programming Language"
  • "HELLO WORLD" → "Hello World"

Требования

  • Реализуйте с использованием StringBuilder
  • Реализуйте с использованием Stream API
  • Обработайте множественные пробелы
  • Остальные буквы в слове должны быть в нижнем регистре

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Капитализация первых букв слов в строке

Объяснение задачи

Нужно преобразовать каждое слово в строке так, чтобы первая буква была заглавной, а остальные — прописные. Например, "hello WORLD" → "Hello World".

Решение 1: StringBuilder (процедурный подход)

Это классический и эффективный способ:

public class StringCapitalizer {
    /**
     * Капитализирует первую букву каждого слова используя StringBuilder
     * Время: O(n), Память: O(n)
     */
    public static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = true;
        
        for (char c : str.toCharArray()) {
            if (Character.isWhitespace(c)) {
                result.append(c);
                capitalizeNext = true;
            } else if (capitalizeNext) {
                result.append(Character.toUpperCase(c));
                capitalizeNext = false;
            } else {
                result.append(Character.toLowerCase(c));
            }
        }
        
        return result.toString();
    }
}

Как работает:

  1. Флаг capitalizeNext отслеживает, нужно ли капитализировать следующий символ
  2. При встречи пробела/whitespace устанавливаем флаг в true
  3. Первый небелый символ после пробела капитализируем
  4. Остальные символы переводим в нижний регистр

Пример работы:

"hello world"
h → capitalizeNext=true → H
e → capitalizeNext=false → e
l → l
l → l
o → o
  → whitespace → capitalizeNext=true
w → capitalizeNext=true → W
o → capitalizeNext=false → o
r → r
l → l
d → d
Результат: "Hello World"

Решение 2: Stream API (функциональный подход)

Для любителей функционального программирования:

import java.util.stream.Collectors;
import java.util.regex.Pattern;

public class StringCapitalizer {
    /**
     * Капитализирует используя Stream API
     */
    public static String capitalizeStream(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        
        // Разбиваем на слова, капитализируем каждое, объединяем
        return Pattern.compile("\\s+")
            .splitAsStream(str)
            .map(StringCapitalizer::capitalizeWord)
            .collect(Collectors.joining(" "));
    }
    
    private static String capitalizeWord(String word) {
        if (word.isEmpty()) return word;
        return word.substring(0, 1).toUpperCase() + 
               word.substring(1).toLowerCase();
    }
}

Минус: этот подход теряет множественные пробелы между словами. Для сохранения пробелов используйте regex lookup:

public static String capitalizeStreamAdvanced(String str) {
    if (str == null || str.isEmpty()) {
        return str;
    }
    
    return Pattern.compile("(\\S+)")
        .matcher(str)
        .replaceAll(mr -> {
            String word = mr.group(1);
            return word.substring(0, 1).toUpperCase() + 
                   word.substring(1).toLowerCase();
        });
}

Решение 3: С обработкой множественных пробелов

Сохраняет точное количество пробелов:

public class StringCapitalizer {
    public static String capitalizePreserveSpaces(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = true;
        
        for (char c : str.toCharArray()) {
            if (Character.isWhitespace(c)) {
                result.append(c);
                capitalizeNext = true;
            } else {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(c));
                    capitalizeNext = false;
                } else {
                    result.append(Character.toLowerCase(c));
                }
            }
        }
        
        return result.toString();
    }
}

Решение 4: Использование regex и метода replaceAll

Компактный способ с регулярными выражениями:

public class StringCapitalizer {
    /**
     * Капитализирует используя regex
     * Шаблон: (\\b\\w) найти границу слова и первую букву
     */
    public static String capitalizeRegex(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        
        return str.toLowerCase()
                  .replaceAll("\\b(\\w)", 
                      mr -> mr.group(1).toUpperCase());
    }
}

Как работает regex:

  • \\b — граница слова
  • (\\w) — первый буквенный символ (захватываем в группу)
  • replaceAll — заменяет на прописную версию

Решение 5: Использование Apache Commons Lang

Если вы уже используете библиотеку:

import org.apache.commons.lang3.text.WordUtils;

public class StringCapitalizer {
    public static String capitalizeCommonsLang(String str) {
        return WordUtils.capitalizeFully(str);
    }
}

Полные тесты

public class CapitalizeTest {
    public static void main(String[] args) {
        // Базовые примеры
        test("hello world", "Hello World");
        test("JAVA PROGRAMMING LANGUAGE", "Java Programming Language");
        test("", "");
        test("a", "A");
        
        // Множественные пробелы
        test("hello   world", "Hello   World");
        
        // Разные whitespace
        test("hello\tworld\ntest", "Hello\tWorld\nTest");
        
        // Смешанный регистр
        test("hElLo wOrLd", "Hello World");
    }
    
    static void test(String input, String expected) {
        String result = StringCapitalizer.capitalize(input);
        boolean pass = result.equals(expected);
        System.out.println((pass ? "✓" : "✗") + " Input: "" + input + 
                         "" → "" + result + """);
    }
}

Сравнение подходов

ПодходЧитаемостьПроизводительностьОбработка пробелов
StringBuilderХорошаяO(n) - лучший вариантСохраняет точно
Stream APIВысокаяO(n) - медленнееТеряет множественные
Regex replaceAllСредняяO(n) - зависит от regexСохраняет
Apache CommonsОтличнаяO(n)Отличная поддержка

Вывод

На интервью рекомендуется:

  1. По умолчанию: StringBuilder решение — показывает эффективность и понимание строк
  2. Альтернатива: Stream API — если интервьюер интересуется функциональным подходом
  3. Упомянуть: что regex решение тоже возможно, но медленнее при частом использовании

Ключевые моменты:

  • StringBuilder избегает создания промежуточных строк
  • Важно обрабатывать multiple whitespace корректно
  • Регулярные выражения мощные, но медленнее для простых случаев