Люди и машины общаются между собой при помощи выстроенных особым образом наборов символов. Символы собираются в слова, а слова — в предложения или строки, из которых создается текст. Какое бы приложение не создавалось, набор символов всегда будет присутствовать, вне зависимости от используемого языка.
Объект String в Java
В языке Java строка является особым объектом и обозначается английским словом String. До версии Java 1.7.0_06 в ее основе лежал массив char value, состоящий из особого типа данных — char. Объектом был 16-битный символ Unicode со значением по умолчанию ‘u0000’. Также присутствовала переменная int offset, которая говорила, с какого символа в этом массиве начинается строка. Переменная int count описывала количество символов, принимаемых строкой, начиная с int offset. Но с появлением Java 9, переменные offset и count перестали использоваться. Еще одним нововведением стала так называемая «концепция compact string». Попытка ввести ее предпринималась и раньше, еще в Java 6, но тогда появились проблемы с производительностью, и от этой идеи отказались.
Вам будет интересно:Загрузка и установка кисти для "Фотошопа" туман
Нововведения в Java 9
Массив char value в новой версии стал byte value, так как по статистике большую часть строк можно было представить символами латинского алфавита. А для них не нужно использовать 2 байта, достаточно одного. Поэтому было принято решение ввести массив байтов и byte coder, который хранит кодировку — latin-1 или utf-16, где в первом случае байт равен нулю, а во втором — единице. В строке для каждого символа выделен 1 байт, и как только встречается символ, который не помещается, для него выделяется 2 байта. Из-за этого длина строки не всегда равна длине массива. Они совпадают только в случае если в нем содержится кодировка latin-1. Строка равна половине длины массива, если кодировкой является utf-16. Также в новой версии появилась константа boolean COMPACT_STRINGS.
Особенности класса String
Класс String — immutable, что означает неизменяемость. Также он final, то есть от него нельзя наследоваться, нельзя сделать какую-то свою строку на основе этого класса. Его объекты нельзя изменять после создания. На самом деле все методы, которые якобы меняют строку, создают новый объект. Основными причинами этого являются безопасность и String pool. Безопасность с точки зрения потоков, заключается в отсутствии необходимости синхронизировать операции. Можно передавать строку между потоками. Поэтому не нужно беспокоится, что строка будет изменена.
Также есть возможность хранить hash-код непосредственно в объекте. Безопасность также состоит в том, что строки можно спокойно передавать в качестве параметров для авторизации, а неизменяемость гарантирует, что в процессе пересылки они не будут перехвачены и изменены. String pool — это некий кэш строк. В памяти, где хранятся объекты, есть место, куда сохраняются строки, созданные путем указания в коде литералов. Для ускорения работы и сохранения памяти можно хранить несколько ссылок на одну строку, если значения их одинаковые. Для реализации изменяемых String существуют специальные классы — StringBuilder и StringBuffer. Оба они практически идентичны, но второй потокобезопасный.
Методы класса String
Со строками можно работать при помощи различных методов. Они позволяют производить следующие действия:
- проводить сравнение длин строк Java;
- извлечение подстроки из строки;
- получать символ по индексу или индекс по символу;
- проверять строку на пустоту;
- узнавать длину одной строки;
- преобразовывать строки в массив;
- менять регистр;
- соединять строки;
- разбивать строку на массив;
- удалять пустые символы вначале и в конце;
- заменять подстроки.
До того, как убрали offset и count метод извлечения подстроки из строки работал немного иначе, чем в новой версии. Он лишь создавал новую оболочку для объекта String, массив при этом оставался старым. Можно было заменить часть строки, но при этом оставалась ссылка на предыдущую версию. Это приводило к утечкам памяти. Избежать подобной проблемы можно было только используя копирующий конструктор. В новой версии Java строка хранит только те данные, которые в нее записаны.
Сравнение двух строк Java
Рассмотрим один из методов более внимательно. Особенно часто применяется специальное действие в языке Java — сравнение строк. У класса String для этого есть два варианта метода compareTo(). Метод compareTo(String anotherString) используется для сравнение строк Java объект String с полученным аргументом String и сопоставляет их лексически. Он вернет int со значением -1 для «меньше», 0 для равенства или 1 для «больше». Этот метод полезен для сортировки алгоритмов. Аналогичный метод для сравнения строк в Java — Equals(). Он использует логические значения равенства и, когда объекты эквивалентны, вернется значение true. Если первый вариант применяется для сортировки, второй нужен для определения равенства. Еще один вариант сравнения строк Java — метод compareToIgnoreCase(String str). Он похож на предыдущий, но игнорирует регистр символов.