Программирование на языке Java

Работа со строками


Глава 9 Работа со строками

В этой главе обсуждаются средства языка Java для работы со строками. В язы­ках С и C++ отсутствует встроенная поддержка такого объекта, как строка. В них при необхо­димости передается адрес последовательности байтов, содержимое которых трактуется как символы до тех пор, пока не будет встречен нулевой байт, отмечающий конец строки. В пакет java.lang встроен класс, инкапсулирующий структуру данных, соответ­ствующую строке. Этот класс, называемый String, не что иное, как объ­ектное представление неизменяемого символьного массива. В этом классе есть методы, которые позволяют сравнивать строки, осуществлять в них поиск и извлекать определенные символы и подстроки. Класс StringBuffer используется тогда, когда строку после создания требу­ется изменять.

ВНИМАНИЕ

И String, и StringBuffer объявлены final, что означает, что ни от одного из этих классов нельзя производить подклассы. Это было сделано для того, чтобы можно было применить некоторые виды оптимизации по­зволяющие увеличить производительность при выполнении операций обработки строк.

 

Конструкторы

Как и в случае любого другого класса, вы можете создавать объекты типа String с помощью оператора new. Для создания пустой строки ис­пользуется конструктор без параметров:

String s = new String():

Приведенный ниже фрагмент кода создает объект s типа String иници­ализируя его строкой из трех символов, переданных конструктору в ка­честве параметра в символьном массиве.

char chars[] = { 'а', 'b', 'с' }:



String s = new String(chars);

System.out.println(s):

Этот фрагмент кода выводит строку «abc». Итак, у этого конструктора — 3 параметра:

String(char chars[], int начальныйИндекс, int числоСимволов);

Используем такой способ инициализации в нашем очередном примере:

char chars[] = { 'a', 'b', 'с', 'd', 'e', 'f' }:

String s = new String(chars,2,3);

System.out.println(s);

Этот фрагмент выведет «cde».

Специальный синтаксис для работы со строками




В Java включено несколько приятных синтаксических дополнений, цель которых — помочь программистам в выполнении операций со строками. В числе таких операций создание объектов типа String слияние нескольких строк и преобразование других типов данных в символьное представление.

Создание строк



Java включает в себя стандартное сокращение для этой опера­ции — запись в виде литерала, в которой содержимое строки заключа­ется в пару двойных кавычек. Приводимый ниже фрагмент кода экви­валентен одному из предыдущих, в котором строка инициализировалась массивом типа char.

String s = "abc";



System.out.println(s);



Один из общих методов, используемых с объектами String — метод length, возвращающий число символов в строке. Очередной фрагмент вы­водит число 3, поскольку в используемой в нем строке — 3 символа.

String s = "abc";



System.out.println(s.length);



В Java интересно то, что для каждой строки-литерала создается свой представитель класса String, так что вы можете вызывать методы этого класса непосредственно со строками-литералами, а не только со ссылоч­ными переменными. Очередной пример также выводит число 3.

System.out.println("abc".Length());



Слияние строк

Строку

String s = «Не is » + age + " years old.";



в которой с помощью оператора + три строки объединяются в одну, про­честь и понять безусловно легче, чем ее эквивалент, записанный с яв­ными вызовами тех самых методов, которые неявно были использованы в первом примере:

String s = new StringBuffer("He is ").append(age);



s.append(" years old.").toString();



По определению каждый объект класса String не может изменять­ся. Нельзя ни вставить новые символы в уже существующую строку, ни поменять в ней одни символы на другие. И добавить одну строку в конец другой тоже нельзя. Поэтому транслятор Java преобразует опера­ции, выглядящие, как модификация объектов String, в операции с род­ственным классом StringBuffer.



ЗАМЕЧАНИЕ

Все это может показаться вам необоснованно сложным. А почему нельзя обойтись одним классом String, позволив ему вести себя при­мерно так же, как StringBuffer? Все дело в производительности. Тот факт, что объекты типа String в Java неизменны, позволяет транслято­ру применять к операциям с ними различные способы оптимизации.

Последовательность выполнения операторов

Давайте еще раз обратимся к нашему последнему примеру:

String s = "Не is " + age + " years old.";



В том случае, когда age — не String, а переменная, скажем, типа int, в этой строке кода заключено еще больше магии транслятора. Целое значение переменной int передается совмещенному методу append класса StringBuffer, который преобразует его в текстовый вид и добавляет в конец содержащейся в объекте строки. Вам нужно быть вниматель­ным при совместном использовании целых выражений и слияния строк, в противном случае результат может получиться совсем не тот, который вы ждали. Взгляните на следующую строку:

String s = "four: " + 2 + 2;



Быть может, вы надеетесь, что в s будет записана строка «four: 4»? Не угадали — с вами сыграла злую шутку последовательность выпол­нения операторов. Так что в результате получа­ется "four: 22".

Для того, чтобы первым выполнилось сложение целых чисел, нужно использовать скобки :

String s = "four: " + (2 + 2);



 



Преобразование строк

В каждом классе String есть метод toString — либо своя собственная реализация, либо вариант по умолчанию, наследуемый от класса Object. Класс в нашем очередном примере замещает наследуемый метод toStrring своим собственным, что позволяет ему выводить значения переменных объекта.

class Point {



int х, у;



Point(int x, int у) {



this.x = х;



this.у = у;



}



public String toString() {



return "Point[" + x + ", " + у + "]";



} }



class toStringDemo {



public static void main(String args[]) {



Point p = new Point(10, 20);



System.out.println("p = " + p);



} }



Ниже приведен результат, полученный при запуске этого примера.


Содержание раздела