Главная » Java » Сравнение строк Java

0

 

Класс String поддерживает механизмы сравнения строк и их отдельных частей. Прежде чем приступить к описанию соответствующих методов, мы должны предупредить, что все они основаны на модели строки, отвечающей спецификации Unicode, и поэтому не принимают в расчет региональные стандарты и вопросы, связанные с локализацией кода. Например, при выполнении операции сравнения строк на предмет того, какая из них "больше", про грамма сопоставляет Uпiсоdе-коды каждого символа обеих строк, но не руководствуется правилами какого-либо конкретного естественного языка. С точки зрения франкоязычного пользователя, например, буквы с и с считаются одинаковыми и различаются только наличием во второй из них диакритического знака. При сортировке строк текста, набранного по-французски, принято игнорировать подобные различия – строка "асb", скажем, будет размещена перед строкой "acz", поскольку буква Ь в алфавите французского языка предшествует букве z. Но в соответствии с правилами Unicode указанные символы приходится считать совершенно различными – в таблице символов Unicode буква с (\uООБЗ) находится перед С (\иООе7), – поэтому Jаvа-программа отсортирует строки по-другому. Вопросы, относящиеся к проблематике региональных стандартов и локализации, освещены в главе 19.

Первый метод сравнения строк, которому следует уделить внимание, – это equals; он возвращает true, если переданный аргумент типа String ссылается На строку с таким же набором символов, который хранится и в текущей строке, Т.е. обе строки обладают одинаковой длиной и в точности теми же символами Unicode, расположенными в одинаковом порядке. Если же аргумент относится к Типу, отличному от String, либо обладает иным содержимым, String.equals Возвращает false. Как мы упоминали в разделе 3.8 на странице 109, такое поведение, предполагающее замену условия тождественности ссылок условием равнозначности содержимого, переопределяет исходные правила, которым следует метод Object.equals.

Для сопоставления строк при условии пренебрежения регистром символов ПРИ меняется метод equalsIgnoreCase. Говоря о "пренебрежении регистром", Мы подразумеваем, что, скажем, символы Ё и ё считаются равнозначными и отличными от Е и е. Символы, для которых не существует аналогов в других регистрах (такие как знаки пунктуации), при сопоставлении считаются равными Только самим себе. Спецификация Unicode предлагает немало любопытных возможностей, связанных с регистром символов, включая, например, понятие регистра заголовка (titlecase). Обработка признака регистра в объектах Stгing выполняется согласно правилам, которым следуют соответствующие методы класса charachter, подробно рассмотренного в разделе 11.1.3 на странице 290.

Для выполнения сортировки строк необходим способ их взаимного сравнения.

Метод compareTo класса String возвращает значение типа int, меньшее нуля, равное нулю или большее нуля, если соответственно строка, представляемая текущим объектом, меньше строки, переданной в качестве параметра метода, равна ей или больше нее. Упорядочение символов выполняется по правилам Unicode. Класс String содержит две перегруженные версии метода compareTo: Первой в виде аргумента передается объект типа String, а второй – объект Object. Класс реализует интерфейс comparable, о котором мы упоминали в разделе 4.1 на странице 126, и второй из названных методов выполняет преобразование параметра Object к типу Stгing, вызывая затем первую версию метода compareTo. Существует также и метод compareToIgnorecase, Выполняющий сравнение без учета регистра символов.

Метод compareTo полезен для внутреннего канонического упорядочения строк. Алгоритмы бинарного поиска, например, требуют наличия отсортированного списка элементов, причем в данном случае совершенно не важно, отвечают ли правила упорядочения тем, которые приняты в конкретном естественном языке. Ниже приведен пример метода, реализующего функции бинарного поиска в контексте класса, в котором имеется упорядоченный массив строк.

private String[] table;

public int position(String key) {

 int 10 = 0;

int hi = table.length – 1;

while (10 <= hi) {

int mid = 10 + (hi – 10) / 2;

int стр = key.compareTo(table[mid]);

                if (стр == о)                                // Элемент найден

return mid;

                else if (стр < о)                        // Поиск в нижней части списка

hi = mid – 1;

                else                                    // Поиск в верхней части списка

10 = mid + 1;

}

return -1;                                                      // Элемент не найден

}

в представленном коде реализован базовый алгоритм бинарного поиска. Сначала вычисляется средняя позиция (mid) диапазона и проверяются условия равенства или неравенства ключевого элемента (key) и элемента, расположенного на этой позиции. Если элементы совпадают, значит, поиск завершен успешно. Если ключевой элемент меньше элемента, занимающего среднюю позицию, диапазон сокращается до нижней половины; в противном случае далее будет просматриваться верхняя половина диапазона. Процесс повторяется до тех пор, пока в списке не будет найден искомый ключевой элемент либо значение нижней границы текущего диапазона не превысит величину верхней границы, свидетельствуя о том, что ключевой элемент в списке отсутствует.

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

 

public boolean regionMatches(i~t start, String other, int ostart, lnt count)

 

 

Метод возвращает true, если каждый символ заданного фрагмента текущей строки совпадает с соответствующим символом фрагмента строки, переданной посредством ссылки оthег. Анализу подвергаются часть текущей строки, начиная с символа на позиции start, и фрагмент строки other, начиная с позиции ostart. Количество символов, участвующих в сравнении, задается значением count.

 

public boolean regionMatches(Boolean ignoreCase, int start, String other, int ostart, lnt count)

 

Эта версия метода действует точно так же, как и предыдущая; единственное отличие состоит в том, что флаг ignoreCase позволяет определить, следует ли в процессе сравнения пренебрегать различиями в регистре символов.

 

 

Первая операция сравнения дает итог, равный false, поскольку на позиции текущей строки находится символ ‘и’, а на позиции 0 литерала "ищи" – символ ‘и’. Во втором случае мы разрешаем про грамме пренебречь различиями в регистре символов, поэтому результат сравнения фрагментов строк равен true. При выполнении третьей операции сравнения мы вновь получаем false, поскольку длина сопоставляемых фрагментов равна теперь 4 и их символы не совпадают даже при игнорировании регистра.

 

 

В методах, подобных regionMatches, задание неверных значений позиций внутри строки влечет получение результата false и не приводит к выбрасыванию исключений. Если в качестве значения ссылочного параметра передается null, генерируется исключение типа NullРоInterException.

 

Простые операции проверки содержимого начальной и Конечной частей строки могут быть выполнены с помощью методов startsWith и endsWith.

public boolean startswith(string prefix, int  start)

Возвращает true, если в текущей строке, начиная с позиции start

           расположена последовательность символов prefi х.                                   ‘

public boolean startsWith(string prefix)

Метод аналогичен предыдущему при условии startsWith (prefiх, 0). public boolean endsWith(String suffix)

Возвращает true, если текущая строка завершается последовательно символов suffiх.

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии