Java 8 строки

Цикл статей «Учебник Java 8».

Следующая статья — «Java 8 автоупаковка и распаковка».
Предыдущая статья — «Java 8 числа».

В Java строки являются объектами класса java.lang.String, который является обычным классом но со специальной поддержкой компилятором. Этот класс представляет строку в виде набора символов UTF-16, где дополнительные символы представляются в виде суррогатных пар, другими словами один символ Юникода может состоять из двух char code unit. Индекс в строке адресует char code unit, а на символ. Дополнительные символы используют две позиции в строке.

char code unit — 16-битный символ char .

char code point — символ юникода. Может состоять из двух char -ов.

Такая путаница из char code unit и char code point произошла из-за того, что первоначально стандарт Юникода 1991 года предполагал 16-битные символы фиксированной длины, однако в последствии он был расширен в 1996 году для возможности представления символов, которым необходимо больше 16 бит.

Все строковые литералы в Java являются объектами класса String .

Примеры создания строк:

Для строковых литералов используются двойный кавычки, а для примитивного типа char  — одинарные.

У класса String  довольно много конструкторов. Можно, например, создать строку на основе массива байт:

Или так:

В этих примерах "ISO-8859-1" — это имя кодировки.

Каждая реализация Java поддерживает следующие виды кодировок:

  • US-ASCII
  • ISO-8859-1
  • UTF-8
  • UTF-16BE
  • UTF-16LE
  • UTF-16

Дополнительно могут поддерживаться другие кодировки, например для Windows обязательно будет поддержка кодировки windows-1251.

Когда компилятор видит строковый литерал, например "Hello world!" , в коде, он создаёт объект класса java.lang.String.

Так как строковые литеры являются объектами, то у них можно вызывать методы:

В Java нет перегрузки операций, но класс строки имеет особую поддержку со стороны компилятора — строк можно соединять с помощью операции «+» (при этом используется java.lang.StringBuilder или java.lang.StringBuffer ):

Конкатенации строковых литералов вида " goes" + " to school." компилятор вычисляет на этапе компиляции, поэтому во время выполнения не будет происходить лишних операций. Можно с помощью «+» разделять строковые константы на несколько строк, компилятор уберёт лишние операции сам и превратит всё в одну строковую литералу:

Каждый объект в Java может участвовать в операции конкатенации (соединения) строк, в этом случае используется метод toString() , (если ссылка на объект равна null, то используется строка "null" ):

Выведет в консоль:

Класс String  НЕ имеет специальной поддержки для == , поэтому сравнивать строки нужно либо через метод equals() , либо equalsIgnoreCase() , либо compareTo() , либо compareToIgnoreCase() .

В Java используется пул строковых литералов. Одинаковые строковые литералы всегда ссылаются на один и тот же экземпляр класса String :

Этот код выведет:

Объяснение:

  1. Одинаковые строковые литералы всегда ссылаются на один и тот же экземпляр класса String.
  2. Экземпляры классы String, вычисленные во время выполнения, создаются заново, автоматически в пуле не участвуют и потому различны.
  3. Строковые литералы в константных выражениях вычисляются на этапе компиляции и затем расцениваются как обычные литералы.
  4. С помощью метода intern() можно добавить строку в пул либо получить ссылку на такую строку из пула.

Многие методы строки принимают в качестве параметра или возвращают в качестве результата индекс. Индексация начинается с нуля. Первый char (имеется в виду char code unit, а не символ, разумеется) в строке имеет индекс 0, а последний имеет индекс length() — 1. Если переданный в параметр индекс выходит за пределы строки, то методы генерируют исключение java.lang.IndexOutOfBoundsException.

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

индексы Java

Подобная индексация является стандартом в Java. Всегда когда указывается отрезок в массиве, строке, списке или ещё-где-то, начальный индекс включается в отрезок, а конечный исключается.

Методы класса java.lang.String

Возвращает char (Unicode code unit) по указанному индексу.

Возвращает символ (Unicode code point) по указанному индексу. Индекс указывается для char-ов.

Лексикографическое сравнение строк. Возвращает -1, если текущая строка лексикографически меньше anotherString, 0 — строки лексикографически равны, 1 — текущая строка лексикографически больше. Метод полезен для сортировки строк.

Лексикографическое сравнение, игнорирующее разницу в регистрах букв.

 

Если длина строки str равна 0, то возвращает this, иначе возвращает строку, являющуюся конкатенацией (объединением) текущей строки и str.

Возвращает true, если текущая строка содержит последовательность символов s. Класс java.lang.String реализует интерфейс java.lang.CharSequence, так что в качестве параметра можно передавать экземпляр класса String.

Возвращает true, если текущая строка заканчивается на suffix или равна ему. Если suffix является пустой строкой, то возвращает true.

Возвращают массив байт, содержащий строку в указанной кодировке.

Возвращает индекс первого вхождения символа ch, начиная с fromIndex. Если символ не найден, то возвращает -1.

 

public int indexOf(String str)

Возвращает индекс первого вхождения подстроки в строке, начиная с fromIndex. Если подстрока не найдена, то возвращает -1.

Форматированный вывод. Более подробно будет рассмотрен в статье про форматирование.

Магический метод. В Java существует пул строк. Этот метод проверяет наличие строки в пуле, если в пуле есть такая строка, то метод возвращает ссылку на неё. Если в пуле нет такой строки, то строка добавляется в пул, и возвращается ссылка на неё. Все строковые литералы и константы автоматически включаются в пул. Примеры:

Объединяет несколько CharSequence  в одну строку, используя в качестве разделителя delimiter.

Возвращает длину строки в char -ах (Unicode code units). Количество символов в строке (Unicode code points) может отличаться от этого значения.

Возвращает true , если length() == 0.

Возвращает строку, в которой все oldChar заменены на newChar. Если oldChar в строке нет, то возвращается исходная строка.

Возвращает строку, в которой все вхождения подстрок согласно регулярному выражению заменены на replacement.

 

Возвращает строку, в которой все вхождения последовательности символов target  заменены на replacement.

Возвращает подстроку, начинающуюся с beginIndex (включительно) до endIndex (исключительно) или конца строки.

Разбивает строку на массив строк по регулярному выражению. Пустые конечные строки не включаются в результирующий массив.

Возвращает true , если строка начинается с prefix либо равна ему. Если prefix является пустой строкой, то возвращается true.

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

Возвращает строку, где все символы приведены в верхний регистр относительно текущей локали или указанной.

Возвращает строку, в которой убраны пробелы в начале и в конце строки. Если строка начинается и заканчивается на непробельные символы (больше '\u0020'), то возвращается ссылка на this.

Возвращает строковое представление объекта. В случае с Object результатом является obj.toString(), если obj != null и "null" в противном случае.

 

и другие методы.

java.lang.StringBuilder

В отличие от String класс StringBuilder позволяет менять содержимое своих экземпляров. В большинстве случаев нужно использовать String, использование же StringBuilder целесообразно в случаях, когда вам нужно соединить большое количество строковых переменных, например перебирая элементы массива или коллекции в цикле.

Так же как и у  String у StringBuilder есть метод length(), позволяющий узнать его длину в char-ах.

В отличие от String у StringBuilder кроме длины есть ещё вместимость/ёмкость (capacity). Вместительность можно узнать с помощью метода capacity(), она всегда больше или равна длине.

 

Конструкторы StringBuilder
Конструктор Описание
StringBuilder()  Создаёт пустой StringBuilder  вместительностью 16 (16 пустых элементов).
StringBuilder(CharSequence cs)  Создаёт StringBuilder , содержащий символы из последовательности и 16 дополнительных пустых элементов.
StringBuilder(int initCapacity)  Создаёт пустой StringBuilder  с начальной вместительностью в initCapacity  элементов.
StringBuilder(String s)  Создаёт StringBuilder , который содержит указанную строку и 16 дополнительных пустых элементов.

StringBuilder содержит пару дополнительных методов, связанных с длиной, которых нет в String:

Длина и вместительность
Метод Описание
void setLength(int newLength)  Устанавливает длину последовательности символов. Если newLength меньше length(), то последние символы обрезаются. Если newLength больше length(), то в конец последовательности добавляются нулевые символы.
void ensureCapacity(int minCapacity)  Обеспечивает, что вместительность будет как минимум равной minCapacity.

Некоторые методы могут увеличить длину последовательности символов в StringBuilder. Если после выполнения подобного метода длина результирующей последовательности окажется больше вместительности, то вместительность автоматически увеличится.

Некоторые методы StringBuilder
Метод Описание
StringBuilder append(boolean b)
StringBuilder append(char c)
StringBuilder append(char[] str)
StringBuilder append(char[] str, int offset, int len)
StringBuilder append(double d)
StringBuilder append(float f)
StringBuilder append(int i)
StringBuilder append(long lng)
StringBuilder append(Object obj)
StringBuilder append(String s) 
Добавляет аргумент, преобразованный в строку, в конец  StringBuilder-а.
StringBuilder delete(int start, int end)
StringBuilder deleteCharAt(int index) 
Первый метод удаляет подпоследовательность с start до end-1 включительно. Второй метод удаляет символ по индексу.
StringBuilder insert(int offset, boolean b)
StringBuilder insert(int offset, char c)
StringBuilder insert(int offset, char[] str)
StringBuilder insert(int index, char[] str, int offset, int len)
StringBuilder insert(int offset, double d)
StringBuilder insert(int offset, float f)
StringBuilder insert(int offset, int i)
StringBuilder insert(int offset, long lng)
StringBuilder insert(int offset, Object obj)
StringBuilder insert(int offset, String s) 
Вставляет второй аргумент, конвертированный в строку, в позицию index.
StringBuilder replace(int start, int end, String s)
void setCharAt(int index, char c) 
Заменяет указанный символ/ы.
StringBuilder reverse()  Меняет порядок символов в StringBuilder на обратный. Первый символ становится последним и так далее.
String toString()  Возвращает строку, содержащую последовательность символов из StringBuilder.

Пример использования StringBuilder:

 

Цикл статей «Учебник Java 8».

Следующая статья — «Java 8 автоупаковка и распаковка».
Предыдущая статья — «Java 8 числа».

Один комментарий к “Java 8 строки”

  1. = Задача
    Читаем строки из текстового файла «onegin.txt» (призовем на помощь классика). Файл имеет размер 297463 байта, utf-8, 27195 слов. Сложим все слова файла в одну строку с использованием всех трех классов и сравним производительность.
    = = Цифры
    (юзаются разные JVM и ОС)
    = Linux
    Класс Open JDK 1.6.0_18 HotSpot 1.6.0_20 JRockit 4.0.1
    String 27390ms 26850ms 26940ms
    StringBuffer 35.55ms 34.87ms 15.41ms
    StringBuilder 33.01ms 31.78ms 12.82ms
    = Windows XP
    Класс HotSpot 1.6.0_20 JRockit 4.0.1
    String 55260ms 45330ms
    StringBuffer 19.38ms 14.50ms
    StringBuilder 16.83ms 12.76ms
    — —
    То есть, при больших файлах, разница в производительности между String и StringBuffer/StringBuilder может быть в несколько сотен раз.
    = Источник
    https://habrahabr.ru/post/102468/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *