String.startsWith: примеры (JAVA)
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
String s = "Пример";
boolean r = s.regionMatches(true, 0, "при", 0, 3);
System.out.println(r);
true
Пояснение: regionMatches позволяет сравнить требуемую длину с опцией игнорировать регистр без создания дополнительных строк.
2) Проверка множества префиксов (эффективно для списка коротких префиксов)
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) Использование в потоках для фильтрации
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) Поиск по смещению в большом буфере (минимизация аллокаций)
String buffer = /* очень длинная строка */ "...";
int pos = 0;
while ((pos = buffer.indexOf('\n', pos)) >= 0) {
// проверка начала следующей строки
if (buffer.startsWith("ERROR", pos+1)) {
// найдено
}
pos++;
}
(нет вывода, пример алгоритма)
5) Безопасная проверка префикса с учётом длины
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
List prefixes = List.of("pre1","pre2","pre3");
String s = "pre2_file";
boolean any = prefixes.stream().anyMatch(s::startsWith);
System.out.println(any);
true
7) Игнорирование регистра без создания новых строк (некоторое ускорение для коротких префиксов)
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 для разбора путей
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 сочетается с другими методами для безопасной и эффективной обработки строк, как избегать лишних аллокаций и как поддерживать нечувствительные к регистру сравнения без преобразования всей строки.