Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Класс String






Практическое занятие №4. Использование строк.

 

Строка в языке Java — это основной носитель текстовой информации. Это не массив символов типа char, а объект соответствующего класса. Системная библиотека Java содержит классы String, StringBuilder и StringBuffer, поддерживающие работу со строками и определенные в пакете java.lang, подключаемом автоматически. Эти классы объявлены как final, что означает невозможность создания собственных порожденных классов со свойствами строки. Для форматирования и обработки строк применяются классы Formatter, Pattern, Matcher и другие.

 

Класс String

Каждая строка, создаваемая с помощью оператора new или с помощью литерала (заключенная в двойные апострофы), является экземпляром класса String. Особенностью объекта класса String является то, что его значение не может быть изменено после создания объекта при помощи какого-либо метода класса, так как любое изменение строки приводит к созданию нового объекта.

Класс String поддерживает несколько конструкторов, например: String(), String(String str), String(byte[] asciichar), String(char[] unicodechar), String(StringBuffer sbuf), String(StringBuilder sbuild) и др. Эти конструкторы используются для создания объектов класса String на основе инициализации значениями из массива типа char, byte и др. Например, при вызове конструктора

new String(str.getBytes(), " UTF-8")

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

String s1 = " oracle.com";

String s2 = new String(" oracle.com");

Класс String содержит следующие методы для работы со строками:

String concat(String s) или «+» — слияние строк;

boolean equals(Object ob) и equalsIgnoreCase(String s) — сравнение строк с учетом и без учета регистра соответственно;

int compareTo(String s) и compareToIgnoreCase(String s) — лексикографическое сравнение строк с учетом и без учета их регистра. Метод осуществляет вычитание кодов первых различных символов вызывающей и передаваемой строки в метод строк и возвращает целое значение. Метод возвращает значение нуль в случае, когда equals() возвращает значение true;

boolean contentEquals(StringBuffer ob) — сравнение строки и содержимого объекта типа StringBuffer;

String substring(int n, int m) — извлечение из строки подстроки длины m-n, начиная с позиции n. Нумерация символов в строке начинается с нуля;

String substring(int n) — извлечение из строки подстроки, начиная с позиции n;

int length() — определение длины строки;

int indexOf(char ch) — определение позиции символа в строке;

static String valueOf(значение) — преобразование переменной базового типа к строке;

String toUpperCase()/toLowerCase () — преобразование всех символов вызывающей строки в верхний/нижний регистр;

String replace(char с1, char с2) — замена в строке всех вхождений первого символа вторым символом;

String intern() — заносит строку в «пул» литералов и возвращает ее объектную ссылку;

String trim() — удаление всех пробелов в начале и конце строки;

char charAt(int position) — возвращение символа из указанной позиции (нумерация с нуля);

boolean isEmpty() — возвращает true, если длина строки равна 0;

char[] getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) — извлечение символов строки в массив символов;

static String format(String format, Object… args), format(Locale l, String

format, Object… args) — генерирует форматированную строку, полученную с использованием формата, интернационализации и др.;

String[] split(String regex), String[] split(String regex, int limit) — поиск вхождения в строку заданного регулярного выражения (разделителя) и деление исходной строки в соответствии с этим на массив строк.

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

Эффективной демонстрацией работы методов класса служит преобразование строки в массив объектов типа String и их сортировка в алфавитном порядке.

Ниже рассмотрена сортировка массива строк методом выбора, таким образом демонстрируются возможности методов класса.

// # 1 # сортировка # SortArray.java

package by.bsac.strings;

public class SortArray {

public static void main(String[ ] args) {

String names = " Alena Alice alina albina Anastasya ALLA ArinA ";

names = names.trim(); // удаление пробелов по краям строки

// разбиение строки на подстроки, где " пробел" — разделитель

String a[ ] = names.split(" "); // массив содержит элементы нулевой длины

for(int j = 0; j < a.length - 1; j++) {

for(int i = j + 1; i < a.length; i++) {

if(a[i].compareToIgnoreCase(a[j]) < 0) {

String temp = a[j];

a[j] = a[i];

a[i] = temp;

}

}

}

for (String arg: a) {

if (! arg.isEmpty()) {

System.out.print(arg + " ");

}

}

}

}

Результат работы программы:

albina Alena Alice alina ALLA Anastasya ArinA

Вызов метода trim() обеспечивает удаление всех начальных и конечных символов пробелов. Метод compareToIgnoreCase() выполняет лексикографическое сравнение строк между собой по правилам Unicode. Оператор

if(! arg.isEmpty()) не позволяет выводить пустые строки.

При использовании методов класса String, изменяющих строку, создается новый обновленный объект класса String. Сохранить произведенные изменения экземпляра класса String можно только с применением оператора присваивания, т.е. установкой ссылки на вновь созданный объект. В следующем примере будет подтвержден тезис о неизменяемости экземпляра типа String.

/* # 2 # передача строки по ссылке # RefString.java */

package by.bsac.strings;

public class RefString {

public static void changeStr(String s) {

s = s.concat(" Certified"); // создается новая строка

// или s.concat(" Certified");

// или s += " Certified";

}

public static void main(String[ ] args) {

String str = new String(" Java");

changeStr(str);

System.out.print(str);

}

}

В результате будет выведена строка:

Java

Поскольку объект был передан по ссылке, любое изменение объекта в методе должно сохраняться и для исходного объекта, так как обе ссылки равноправны. Это не происходит по той причине, что вызов метода concat(String s) приводит к созданию нового объекта.

При создании экземпляра класса String путем присваивания его ссылки на литерал, последний помещается в так называемый «пул литералов». Если в дальнейшем будет создана еще одна ссылка на литерал, эквивалентный ранее объявленному, то будет произведена попытка добавления его в «пул литералов». Так как идентичный литерал там уже существует, то дубликат не может быть размещен, и вторая ссылка будет на существующий литерал. Аналогично в случае, если литерал является вычисляемым. То есть компилятор воспринимает литералы " Java " и " J " + " ava " как эквивалентные.

// # 3 # сравнение ссылок и объектов # EqualStrings.java

package by.bsac.strings;

public class EqualStrings {

public static void main(String[ ] args) {

String s1 = " Java";

String s2 = " Java";

String s3 = new String(" Java");

String s4 = new String(s1);

System.out.println(s1 + " ==" + s2 + ": " + (s1 == s2)); // true

System.out.println(s3 + " ==" + s4 + ": " + (s3 == s4)); // false

System.out.println(s1 + " ==" + s3 + ": " + (s1 == s3)); // false

System.out.println(s1 + " equals " + s2 + ": " + s1.equals(s2)); // true

System.out.println(s1 + " equals " + s3 + ": " + s1.equals(s3)); // true

}

}

В результате, например, будет выведено:

Java==Java: true

Java==Java: false

Java==Java: false

Java equals Java: true

Java equals Java: true

Несмотря на то, что одинаковые по значению строковые объекты расположены в различных участках памяти, значения их хэш-кодов совпадают.

Так как в Java все ссылки хранятся в стеке, а объекты — в куче, то при создании объекта s2 сначала создается ссылка, а затем этой ссылке устанавливается в соответствие объект. В данной ситуации s2 ассоциируется с уже существующим литералом, так как объект s1 уже сделал ссылку на этот литерал. При создании s3 происходит вызов конструктора, т. е. выделение памяти происходит раньше инициализации, и в этом случае в куче создается новый объект.

Существует возможность сэкономить память и переопределить ссылку с объекта на литерал при помощи вызова метода intern().

// # 4 # занесение в пул литералов # DemoIntern.java

package by.bsac.strings;

public class DemoIntern {

public static void main(String[ ] args) {

String s1 = " Java"; // литерал и ссылка на него

String s2 = new String(" Java");

System.out.println(s1 == s2); // false

s2 = s2.intern();

System.out.println(s1 == s2); // true

}

}

В данной ситуации ссылка s1 инициализируется литералом, обладающим всеми свойствами объекта вплоть до вызова методов. Вызов метода intern() организует поиск в «пуле литералов» соответствующего значению объекта s2 литерала и при положительном результате возвращает ссылку на найденный литерал, а при отрицательном — заносит значение в пул и возвращает ссылку на него.

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.014 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал