String.startsWith: примеры (JAVA)

Примеры и объяснения работы метода startsWith
Раздел: Строки (String) - поиск и сравнение
String.startsWith(String prefix, int toffset): boolean

Общее описание

Метод String.startsWith в Java проверяет, начинается ли строка с указанного префикса. Используется при валидации префиксов, маршрутизации по строкам, разборе путей и любая ситуация, где требуется быстрое сравнение начала строки.

Сигнатуры:

  • boolean startsWith(String prefix) - возвращает true, если текущая строка начинается с prefix (начало с позиции 0).
  • boolean startsWith(String prefix, int toffset) - возвращает true, если подстрока текущей строки, начиная с индекса toffset, начинается с prefix.

Поведение и возможные значения:

  • Возвращает true или false в зависимости от совпадения. Сравнение чувствительно к регистру.
  • Если аргумент prefix равен null, выбрасывается NullPointerException.
  • Если toffset отрицательный или значение индекса выходит за допустимые границы (например, не хватает символов после toffset для полного совпадения), метод возвращает false; при этом исключений не генерируется (кроме случая с prefix == null).
  • Метод работает на основе кодовых единиц UTF-16 Java-строки; он сравнивает последовательность char без учета локали.

Короткие примеры использования

Примеры с разными вариантами параметров и возможными результатами.

1) Простая проверка префикса

String s = "hello world";
boolean r = s.startsWith("hello");
System.out.println(r);
true

2) Проверка с указанием смещения

String s = "file.tar.gz";
boolean r1 = s.startsWith("tar", 5);
boolean r2 = s.startsWith("tar", 6);
System.out.println(r1);
System.out.println(r2);
true
false

3) Регистр имеет значение

String s = "Java";
System.out.println(s.startsWith("ja"));
false

4) Null в качестве префикса

String s = "x";
// s.startsWith(null) -> NullPointerException
Exception in thread "main" java.lang.NullPointerException
	at java.base/java.lang.String.startsWith(String.java:...)

5) Смещение вне диапазона

String s = "abc";
System.out.println(s.startsWith("", 5));
false

Похожие методы в Java

Короткий обзор альтернатив и особенности их применения.

  • regionMatches: позволяет сравнивать фрагменты строк, включая опцию игнорирования регистра regionMatches(ignoreCase, toffset, other, ooffset, len). Удобен при необходимости сравнения с игнорированием регистра или частичного сравнения.
  • indexOf: s.indexOf(prefix) == 0 эквивалент проверки начала, но возвращает позицию первого вхождения; полезен, когда нужна позиция, а не булево значение.
  • matches (regex): можно использовать регулярные выражения, например s.matches("^prefix.*"), но это тяжелее по производительности и сложнее для простых префиксов.
  • substring + equals: s.substring(0, n).equals(prefix) - рабочий способ, однако менее безопасен из‑за возможных исключений при неверной длине и менее выразителен.

Выбор зависит от задачи: для простого точного префикса лучше startsWith, для сравнения без учета регистра - regionMatches(true, ...), для поиска позиции - indexOf, для гибких шаблонов - регулярные выражения.

Аналоги в других языках

Краткие отличия и примеры.

  • JavaScript: String.prototype.startsWith(prefix[, position]). Чувствителен к регистру. Пример:
    const s = 'Hello';
    console.log(s.startsWith('He'));
    true
  • Python: str.startswith(prefix[, start[, end]]). Поддерживает кортеж префиксов и диапазон. Пример:
    s = 'hello'
    print(s.startswith(('h','H')))
    True
  • PHP: в PHP 8 есть str_starts_with(string, prefix). Ранее использовались strpos или substr_compare. Пример:
    var_dump(str_starts_with('abc', 'a'));
    bool(true)
  • C#: string.StartsWith(string, StringComparison). Поддерживает сравнение с учетом культуры и игнорирование регистра, что дает больше гибкости по локали. Пример:
    Console.WriteLine("Straße".StartsWith("Str", StringComparison.OrdinalIgnoreCase));
    True
  • Go: пакет strings, функция strings.HasPrefix(s, prefix). Пример:
    fmt.Println(strings.HasPrefix("abc", "a"))
    true
  • Kotlin: String.startsWith(prefix, ignoreCase = false). Поддерживает флаг игнорирования регистра напрямую. Пример:
    println("Hello".startsWith("he", true))
    true
  • Lua: нет встроенного метода, обычно сравнивается с помощью string.sub. Пример:
    print(string.sub('abc',1,1) == 'a')
    true
  • SQL: обычно используется LIKE 'prefix%' или функции LEFT(col, n) = prefix. Поведение и чувствительность к регистру зависят от колlation.

Отличие от Java: в C# и Kotlin встроена поддержка сравнения с учетом культуры или игнорирования регистра; в Python можно передавать несколько префиксов как кортеж; в PHP до версии 8 требовались обходные пути.

Типичные ошибки и нюансы

Наиболее частые ошибки при использовании и их последствия.

  • Передача null как префикса. Приводит к NullPointerException.
    String s = "a";
    s.startsWith(null);
    Exception in thread "main" java.lang.NullPointerException
    	at java.base/java.lang.String.startsWith(String.java:...)
  • Ожидание игнорирования регистра. Метод чувствителен к регистру; для нечувствительного сравнения требуется использование regionMatches(true,...) или приведение регистра.
  • Индексы и границы. Ошибка при использовании substring(0, n).equals(prefix) без проверки длины может привести к StringIndexOutOfBoundsException. В отличие от этого startsWith(prefix, toffset) при неправильном смещении возвращает false, а не бросает исключение.
    String s = "a";
    // опасно
    s.substring(0, 5).equals("...");
    Exception in thread "main" java.lang.StringIndexOutOfBoundsException: begin 0, end 5, length 1
  • Путаница с кодовыми точками Unicode. Метод сравнивает char-последовательности. При работе с суррогатными парами или составными символами следует учитывать, что сравнение производится по UTF-16 code units, а не по пользовательским графемам.

Изменения в последних версиях

Метод startsWith присутствует в Java с ранних версий и явных изменений в его сигнатуре не было. Поведение и производительность оставались стабильными. Более новые версии JDK оптимизировали внутренние реализации класса String, что может положительно влиять на скорость операций с строками, включая startsWith, но публичный контракт метода не менялся.

Расширенные и редкие сценарии применения

Несколько подробных примеров с объяснениями и выводом.

1) Игнорирование регистра безопасным способом с regionMatches

Пример java
String s = "Пример";
boolean r = s.regionMatches(true, 0, "при", 0, 3);
System.out.println(r);
true

Пояснение: regionMatches позволяет сравнить требуемую длину с опцией игнорировать регистр без создания дополнительных строк.

2) Проверка множества префиксов (эффективно для списка коротких префиксов)

Пример java
String s = "application/json";
String[] prefixes = {"text/","application/","image/"};
boolean ok = false;
for (String p : prefixes) {
    if (s.startsWith(p)) { ok = true; break; }
}
System.out.println(ok);
true

3) Использование в потоках для фильтрации

Пример java
List list = List.of("a.txt","b.log","a.csv");
list.stream()
    .filter(s -> s.startsWith("a"))
    .forEach(System.out::println);
a.txt
a.csv

4) Поиск по смещению в большом буфере (минимизация аллокаций)

Пример java
String buffer = /* очень длинная строка */ "...";
int pos = 0;
while ((pos = buffer.indexOf('\n', pos)) >= 0) {
    // проверка начала следующей строки
    if (buffer.startsWith("ERROR", pos+1)) {
        // найдено
    }
    pos++;
}
(нет вывода, пример алгоритма)

5) Безопасная проверка префикса с учётом длины

Пример java
String s = "ab";
String p = "abc";
boolean safe = p != null && s.length() >= p.length() && s.startsWith(p);
System.out.println(safe);
false

6) Проверка по шаблону с несколькими вариантами через stream и anyMatch

Пример java
List prefixes = List.of("pre1","pre2","pre3");
String s = "pre2_file";
boolean any = prefixes.stream().anyMatch(s::startsWith);
System.out.println(any);
true

7) Игнорирование регистра без создания новых строк (некоторое ускорение для коротких префиксов)

Пример java
boolean startsIgnoreCase(String s, String prefix) {
    if (prefix == null) throw new NullPointerException();
    if (prefix.length() > s.length()) return false;
    return s.regionMatches(true, 0, prefix, 0, prefix.length());
}

System.out.println(startsIgnoreCase("Hello","he"));
true

8) Совместное использование с Path/URI для разбора путей

Пример java
String uri = "https://example.com/api/v1/resource";
if (uri.startsWith("https://example.com/api/")) {
    String resource = uri.substring("https://example.com/api/".length());
    System.out.println(resource);
}
v1/resource

Эти примеры показывают, как startsWith сочетается с другими методами для безопасной и эффективной обработки строк, как избегать лишних аллокаций и как поддерживать нечувствительные к регистру сравнения без преобразования всей строки.

джава String.startsWith function comments

En
String.startsWith Tests if this string starts with the specified prefix