Специальные строковые операции
Обработка строк
Строка в Java — это последовательность символов. Но, в отличие от многих языков, которые реализуют строки как символьные массивы, в Java строки реализуются как объекты типа string.
Реализация строк в виде встроенных объектов обеспечивает полный комплект свойств, которые делают обработку строк очень удобной. Например, в Java существуют методы для сравнения двух строк, поиска подстроки, конкатенации (сцепления) двух строк и изменения регистра символов строки. Имеется несколько способов создания string-объектов, что облегчает их построение.
Несколько неожиданно, что после создания string-объекта символы, входящие в строку, нельзя изменять. Сначала это кажется серьезным ограничением. Однако это не так. Над этим объектом можно выполнять все типы строковых операций. Для того чтобы изменить версию существующей строки, нужно создать новый объект типа string, который содержит необходимую модификацию. Исходная строка остается неизменной. Этот подход используется, потому что фиксированные, неизменяемые строки можно реализовать более эффективно, чем изменяемые. Для тех случаев, когда желательна изменяемая строка, существует компаньон класса string с именем stringBuffer, чьи объекты содержат строки, которые могут изменяться после их создания.
Классы string и stringBuffer определены в пакете java.lang. Таким образом, они доступны всем программам автоматически. Оба объявлены как final, что означает, что ни один из этих классов не может иметь подклассов. При этом допускаются некоторые оптимизации, которые увеличивают эффективность строковых операций.
Когда говорят, что строки в объектах типа string являются неизменяемыми, это означает, что содержимое string-объекта не может быть модифицировано после того, как он был создан. Однако переменную, объявленную как string-ссылка, можно в любое время изменить так, чтобы она указывала на другой string-объект.
String-конструкторы
Класс string поддерживает несколько конструкторов. Чтобы создать пустой объект типа string, нужно вызвать умалчиваемый конструктор. Например, следующий оператор
String s = new String();
создает экземпляр класса string, не содержащий символов (т. е. пустую строку).
Часто необходимо создавать строки с начальными значениями. Для этого в классе string определен ряд конструкторов. Чтобы создать string-объект, инициализированный массивом символов, используйте следующий конструктор:
String(char chars[ ])
Например:
char chars[] = { 'a', 'b', 'c' };
String s = new String(chars);
Этот конструктор инициализирует (объектную) переменную s строкой "abc".
В качестве инициализатора можно указать поддиапазон символьного массива, для чего используется следующий конструктор:
String(char chars[ ], int startIndex, int ntanChars)
где startindex определяет индекс, с которого начинается поддиапазон; numchars определяет число символов в диапазоне. Например:
char chars [] = { 'a', 'b', 'с', 'd’ 'е’ 'f’ };
String s = new String (chars, 2, 3);
что инициализирует строчный объект s символами cde.
Поскольку строки в Java представляются массивами, то для символьных компонентов строки используется терминология массивов, где индекс — это просто порядковый номер символа (точнее его позиции) в строке, причем нумерация выполняется как в массиве — с нуля.
С помощью конструктора
String(String strObj)
можно создать string-объект, который содержит такую же символьную последовательность, как другой string-объект. Здесь strcbj — объект типа string. Рассмотрим следующий пример:
// Построение одного String-объекта из другого.
class MakeString {
public static void main(String args[]) {
char c[] = {'J', 'a', 'v', 'a'};
String s1 = new String (c);
String s2 = new String(s1);
System.out.println(s1);
System.out.println(s2);
}
}
Вывод этой программы:
Java Java
Как вы видите, s1 и s2 содержат одну и ту же строку.
Тип char в Java использует 16-разрядное представление символов (из набора Unicode), тогда как в Internet для представления строчных символов используется 8-разрядный набор символов ASCII. Поскольку 8-разрядные строки ASCII используются достаточно широко, в классе string имеются конструкторы, которые инициализируют строку 8-разрядными byte-массивами. Формы этих конструкторов таковы:
String(byte asciiChars[])
String(byte asciiChars[], int startIndex, int numChars)
где asciichars указывает байтовый массив. Вторая форма позволяет указать поддиапазон. В каждом из этих конструкторов преобразование байтов в символы использует кодовый набор символов платформы, заданный по умолчанию. Следующая программа иллюстрирует использование этих конструкторов:
// Создание строки из подмножества символьного массива.
class SubStringCons {
public static void main(String args[]) {
byte ascii[] = {65, 66, 67, 68, 69, 70 };
String s1 = new String(ascii);
System.out.println(s1);
String s2 = new String(ascii, 2, 3);
System.out.println(s2);
}
}
Эта программа генерирует следующий вывод:
ABCDEF CDE
Определены также расширенные версии преобразующих конструкторов, где можно указать иные кодовые наборы для кодирования символов. Однако большую часть времени вы будете использовать кодирование, применяемое платформой по умолчанию.
Всякий раз, когда вы создаете string-объект из массива, содержимое массива копируется. Если вы изменяете содержимое массива после того, как создали строку, string-объект останется неизменным.
Длина строки
Длина строки определяется количеством содержащихся в ней символов. Для получения этого значения вызовите метод length() в форме:
int length()
Следующий фрагмент выведет число 3, т. к. в строке s имеется три символа:
char chars[] = { 'a', 'b', 'с' };
String s = new String(chars);
System.out.println(s.length());
Специальные строковые операции
Поскольку работа со строками — обычная и очень важная часть программирования, в синтаксис языка Java добавлена поддержка для некоторых специальных строковых операций. К этим операциям относятся автоматическое создание новых string-объектов из строковых литералов, конкатенация множественных string-объектов при помощи операции + и преобразование других типов данных в строковое представление. Существуют явные методы для реализации всех этих функций, но Java выполняет их автоматически как для удобства программиста, так и для того, чтобы сделать запись программы более ясной.
Строковые литералы
Предыдущие примеры показали, как можно явно создавать string-объекты из массива символов, используя операцию new. Однако есть более простой способ — можно для этой же цели использовать строковый литерал. Для каждого строкового литерала в программе Java автоматически создает string-объект. Например, следующий кодовый фрагмент создает две эквивалентные строки:
char chars[] = { 'a', 'b', 'с' };
String s1 = new String(chars);
String s2 = "abc"; // использование строкового литерала
Поскольку объект типа string создается для каждого строкового литерала, то этот литерал можно применять в любом месте, где указывается string-объект. Например, разрешается вызывать методы, используя строку в кавычках прямо на месте объектной ссылки, как показано в следующем операторе:
System.out.println{"abc".length());
Здесь строчный литерал ("abc") указан на месте, где должна бы была стоять объектная ссылка s2 из предыдущего фрагмента. Аргумент "abc".length о вызывает метод length о прямо для строки "abc" (вместо того, чтобы вызвать его для объекта s2). Как и ожидается, оператор напечатает число "3".
Конкатенация строк
Вообще, Java не разрешает применять операции к string-объектам. Однако в этом правиле есть одно исключение. Это операция +, которая связывает две строки, строя в результате string-объект с объединенной последовательностью символов. Можно также организовать цепочку из нескольких + операций. Например, следующий фрагмент связывает три строки:
String age = "9";
String s = "Ему " + age + " лет.";
System.out.println(s);
Здесь происходит конкатенация (сцепление) трех строк, в результате которой на экран выводится строка "Ему 9 лет.".
Еще одно практическое использование конкатенации — это создание очень длинных строк. Вместо ввода длинных последовательностей символов в исходный код можно разбить их на меньшие части и использовать цепочку + операций для их сцепления. Например:
// Использование конкатенации для создания длинных строк.
class ConCat {
public static void main(String args[]) {
String longStr = "Это была бы очень длинная строка, " +
"не удобная ни для ввода, ни для вывода. " +
"Но конкатенация строк " +
"устраняет этот недостаток.";
System.out.println(longStr);
}
}