Java — strings class
Содержание:
Введение в строки. Класс String
Последнее обновление: 31.10.2018
Строка представляет собой последовательность символов. Для работы со строками в Java определен класс String, который предоставляет ряд методов для манипуляции строками.
Физически объект String представляет собой ссылку на область в памяти, в которой размещены символы.
Для создания новой строки мы можем использовать один из конструкторов класса String, либо напрямую присвоить строку в двойных кавычках:
public static void main(String[] args) { String str1 = "Java"; String str2 = new String(); // пустая строка String str3 = new String(new char[] {'h', 'e', 'l', 'l', 'o'}); String str4 = new String(new char[]{'w', 'e', 'l', 'c', 'o', 'm', 'e'}, 3, 4);//3 -начальный индекс, 4 -кол-во символов System.out.println(str1); // Java System.out.println(str2); // System.out.println(str3); // hello System.out.println(str4); // come }
При работе со строками важно понимать, что объект String является неизменяемым (immutable). То есть при любых операциях
над строкой, которые изменяют эту строку, фактически будет создаваться новая строка
Поскольку строка рассматривается как набор символов, то мы можем применить метод length() для нахождения длины строки или длины набора символов:
String str1 = "Java"; System.out.println(str1.length()); // 4
А с помощью метода toCharArray() можно обратно преобразовать строку в массив символов:
String str1 = new String(new char[] {'h', 'e', 'l', 'l', 'o'}); char[] helloArray = str1.toCharArray();
Строка может быть пустой. Для этого ей можно присвоить пустые кавычки или удалить из стоки все символы:
String s = ""; // строка не указывает на объект if(s.length() == 0) System.out.println("String is empty");
В этом случае длина строки, возвращаемая методом length(), равна 0.
Класс String имеет специальный метод, который позволяет проверить строку на пустоту — isEmpty(). Если строка пуста, он возвращает true:
String s = ""; // строка не указывает на объект if(s.length() == 0) System.out.println("String is empty");
Переменная String может не указывать на какой-либо объект и иметь значение null:
String s = null; // строка не указывает на объект if(s == null) System.out.println("String is null");
Значение null не эквивалентно пустой строке. Например, в следующем случае мы столкнемся с ошибкой выполнения:
String s = null; // строка не указывает на объект if(s.length()==0) System.out.println("String is empty"); // ! Ошибка
Так как переменная не указывает ни на какой объект String, то соответственно мы не можем обращаться к методам объекта String.
Чтобы избежать подобных ошибок, можно предварительно проверять строку на null:
String s = null; // строка не указывает на объект if(s!=null && s.length()==0) System.out.println("String is empty");
Основные методы класса String
Основные операции со строками раскрывается через методы класса String, среди которых можно выделить следующие:
-
concat(): объединяет строки
-
valueOf(): преобразует объект в строковый вид
-
join(): соединяет строки с учетом разделителя
-
сompare(): сравнивает две строки
-
charAt(): возвращает символ строки по индексу
-
getChars(): возвращает группу символов
-
equals(): сравнивает строки с учетом регистра
-
equalsIgnoreCase(): сравнивает строки без учета регистра
-
regionMatches(): сравнивает подстроки в строках
-
indexOf(): находит индекс первого вхождения подстроки в строку
-
lastIndexOf(): находит индекс последнего вхождения подстроки в строку
-
startsWith(): определяет, начинается ли строка с подстроки
-
endsWith(): определяет, заканчивается ли строка на определенную подстроку
-
replace(): заменяет в строке одну подстроку на другую
-
trim(): удаляет начальные и конечные пробелы
-
substring(): возвращает подстроку, начиная с определенного индекса до конца или до определенного индекса
-
toLowerCase(): переводит все символы строки в нижний регистр
-
toUpperCase(): переводит все символы строки в верхний регистр
Разберем работу этих методов.
НазадВперед
4 Класс Boolean
Тип практически такой же, как тип . Отличия минимальны.
Ниже мы покажем упрощенный вариант класса :
Код | Описание |
---|---|
Константы: и Переменная-значение Конструктор класса Метод возвращает значение внутренней переменной-значения Этот статический метод умеет преобразовывать в и в . |
В типе есть две константы (два поля):
Константы класса | Аналог типа boolean | Описание |
---|---|---|
истина | ||
ложь |
Работать с ними можно так же, как и с типом :
Код | Примечание |
---|---|
— единственный класс, который можно писать внутри условия | |
Все три переменные равны / | |
Константы можно сравнивать и через и через Так тоже будет работать. |
Autoboxing тут работает отлично, поэтому можете пользоваться этим типом так же, как типом : никаких подводных камней тут нет.
Как записано | Как это работает |
---|---|
А вот как происходят сравнения между типами и :
Если очень нужно создать независимый объект , то надо создать его явно:
И еще один пример: использование внутри :
Код | Примечание |
---|---|
Скомпилируется и будет работать |
Скомпилируется, но работать не будет:
Код | Примечание |
---|---|
Ошибка. В этой строке кинется исключение |
Структура программы
Последнее обновление: 12.04.2018
Основным строительным блоком программы на языке Java являются инструкции (statement).
Каждая инструкция выполняет некоторое действие, например, вызовы методов, объявление переменных и присвоение им значений. После завершения инструкции в Java ставится точка с запятой (;). Данный знак указывает компилятору на
конец инструкции. Например:
System.out.println("Hello Java!");
Данная строка представляет вызов метода , который выводит на консоль строку «Hello Java!». В данном случае вызов
метода является инструкцией и поэтому завершается точкой с запятой.
Кроме отдельных инструкций распространенной конструкцией является блок кода. Блок кода содержит набор инструкций, он заключается в фигурные скобки, а инструкции помещаются между открывающей и закрывающей фигурными скобками:
{ System.out.println("Hello!"); System.out.println("Welcome to Java!"); }
В этом блоке кода две инструкции, которые выводят на консоль определенную строку.
Выполнение программы. Метод main
Java является объектно-ориентированным языком, поэтому всю программу можно представить как набор взаимодействующих между собой классов и объектов.
В первой главе при создании первого приложения программа была определена следующим образом:
public class Program{ public static void main (String args[]){ System.out.println("Hello Java!"); } }
То есть основу нашей программы составляет класс Program. При определении класса вначале идет модификатор доступа public,
который указывает, что данный класс будет доступен всем, то есть мы сможем его запустить из командной строки. Далее идет ключевое слово class,
а затем название класса. После названия класса идет блок кода, в котором расположено содержимое класса.
Входной точкой в программу на языке Java является метод main, который определен в классе Program. Именно с него начинается
выполнение программы. Он обязательно должен присутствовать в программе. При этом его заголовок может быть только таким:
public static void main (String args[])
При запуске приложения виртуальная машина Java ищет в главном классе программы метод main с подобным заголовком, и после его обнаружения запускает его.
Вначале заголовка метода идет модификатор , который указывает, что метод будет доступен извне. Слово указывает, что метод
main — статический, а слово — что он не возвращает никакого значения. Далее в скобках у нас идут параметры метода — —
это массив args, который хранит значения типа String, то есть строки. При запуске программы через этот массив мы можем передать в программу различные данные.
После заголовка метода идет его блок, который содержит набор выполняемых инструкций.
Комментарии
Код программы может содержать комментарии. Комментарии позволяют понять смысл программы, что делают те или иные ее части. При компиляции комментарии
игнорируются и не оказывают никакого влияния на работу приложения и на его размер.
В Java есть два типа комментариев: однострочный и многострочный. Однострочный комментарий размещается на одной строке после двойного слеша //.
А многострочный комментарий заключается между символами /* текст комментария */. Он может размещаться на нескольких строках.
Например:
/* многострочный комментарий Объявление нового класса, который содержит код программы */ public class Program{ // начало объявления класса Program // определение метода main public static void main (String args[]){ // объявление нового метода System.out.println("Hello Java!"); // вывод строки на консоль } // конец объявления нового метода } // конец объявления класса Program
НазадВперед
Java Strings are Immutable
In Java, strings are immutable. This means, once we create a string, we cannot change that string.
To understand it more deeply, consider an example:
Here, we have created a string variable named example. The variable holds the string «Hello! «.
Now suppose we want to change the string.
Here, we are using the method to add another string World to the previous string.
It looks like we are able to change the value of the previous string. However, this is not .
Let’s see what has happened here,
- JVM takes the first string «Hello! «
- creates a new string by adding «World» to the first string
- assign the new string «Hello! World» to the example variable
- the first string «Hello! « remains unchanged
JSON
Сериализация и Десериализация
JSON — невероятно удобный и полезный синтаксис для хранения и обмена данными. Java полностью поддерживает это.
Прим. перев. Для использования JSON из примера необходимо подключить библиотеку JSON Simple.
Вы можете сериализовать данные следующим образом:
Получается следующая строка JSON:
Десериализация в Java выглядит так:
Используемый в примере файл JSON (jsonDemoFile.json):
Прим. перев. В Java проектах очень часто для работы с JSON используют библиотеки Gson от Google или Jackson. Обе библиотеки очень популярны и хорошо поддерживаются. Попробуйте и их.
Классы StringBuilder и StringBuffer
Давайте теперь разберемся со StringBuilder и StringBuffer классами. По сути дела, это почти одинаковые классы. Единственное различие между ними: StringBuffer работает медленнее, но он потокобезопасный. Его использование целесообразно при написании программ на многопоточность.
Если Вы посмотрите на код выше, то последний метод, который я написал была конкатенация строк. То есть простое объединение строк в одну. Когда Вы работаете с классом String, результатом такой операции будет новый объект. Если программа конкатенирует много строк это может существенно потребить ресурсы памяти. В отличие от String классы StringBuilder, StringBuffer конкатенируют строки не создавая новый объект. У них есть метод append().
- StringBuilder string = new StringBuilder(«Hello world»);
- String str = «!!!»;
- System.out.println(string.append(str));//Hello world!!!
Все остальные методы которые есть у класса String есть у данных классов.
Теперь Вы знаете больше о строках в Java. Предлагаю закрепить наши знания и написать небольшую программу для проверки логина и пароля. Пользователь вводит логин и пароль; если пароль совпадает, то вывести в консоль приветствие.
Вот что у меня получилось:
- package com.string;
- import java.util.Scanner;
- public class StringVariables {
- private final static String PASSWORD = «pass43_4L»;
- private final static String LOGIN = «user»;
- public static void main(String args) {
- System.out.println(«Введите логин»);
- Scanner in = new Scanner(System.in);
- String login = in.nextLine();
- System.out.println(«Введите пароль»);
- String password = in.nextLine();
- if (LOGIN.equalsIgnoreCase(login)){
- if (PASSWORD.equals(password)){
- System.out.println(«Приветствую » + login);
- }
- else {
- System.out.println(«Неверный пароль»);
- }
- }
- else
- System.out.println(«Неверный логин»);
- }
- }
Разделение
Класс Java String содержит метод split(), который можно использовать для разделения String на массив объектов String:
String source = "A man drove with a car."; String[] occurrences = source.split("a");
После выполнения этого кода Java массив вхождений будет содержать экземпляры String:
"A m" "n drove with " " c" "r."
Исходная строка была разделена на символы a. Возвращенные строки не содержат символов a. Символы a считаются разделителями для деления строки, а разделители не возвращаются в результирующий массив строк.
Параметр, передаваемый методу split(), на самом деле является регулярным выражением Java, которые могут быть довольно сложными. Приведенное выше соответствует всем символам, даже буквам нижнего регистра.
Метод String split() существует в версии, которая принимает ограничение в качестве второго параметра — limit:
String source = "A man drove with a car."; int limit = 2; String[] occurrences = source.split("a", limit);
Параметр limit устанавливает максимальное количество элементов, которое может быть в возвращаемом массиве. Если в строке больше совпадений с регулярным выражением, чем заданный лимит, то массив будет содержать совпадения с лимитом — 1, а последним элементом будет остаток строки из последнего среза — 1 совпадением. Итак, в приведенном выше примере возвращаемый массив будет содержать эти две строки:
"A m" "n drove with a car."
Первая строка соответствует регулярному выражению. Вторая — это остальная часть строки после первого куска.
Выполнение примера с ограничением 3 вместо 2 приведет к тому, что эти строки будут возвращены в результирующий массив String:
"A m" "n drove with " " car."
Обратите внимание, что последняя строка по-прежнему содержит символ в середине. Это потому, что эта строка представляет остаток строки после последнего совпадения (a после ‘n водил с’)
Выполнение приведенного выше примера с пределом 4 или выше приведет к тому, что будут возвращены только строки Split, поскольку в String есть только 4 совпадения с регулярным выражением a.
Класс Thread
В Java функциональность отдельного потока заключается в классе Thread. И чтобы создать новый поток, нам надо создать
объект этого класса. Но все потоки не создаются сами по себе. Когда запускается программа, начинает работать главный поток этой программы.
От этого главного потока порождаются все остальные дочерние потоки.
С помощью статического метода Thread.currentThread() мы можем получить текущий поток выполнения:
public static void main(String[] args) { Thread t = Thread.currentThread(); // получаем главный поток System.out.println(t.getName()); // main }
По умолчанию именем главного потока будет .
Для управления потоком класс Thread предоставляет еще ряд методов. Наиболее используемые из них:
-
getName(): возвращает имя потока
-
setName(String name): устанавливает имя потока
-
getPriority(): возвращает приоритет потока
-
setPriority(int proirity): устанавливает приоритет потока. Приоритет является одним из ключевых факторов для выбора
системой потока из кучи потоков для выполнения. В этот метод в качестве параметра передается числовое значение приоритета — от 1 до 10.
По умолчанию главному потоку выставляется средний приоритет — 5. -
isAlive(): возвращает true, если поток активен
-
isInterrupted(): возвращает true, если поток был прерван
-
join(): ожидает завершение потока
-
run(): определяет точку входа в поток
-
sleep(): приостанавливает поток на заданное количество миллисекунд
-
start(): запускает поток, вызывая его метод
Мы можем вывести всю информацию о потоке:
public static void main(String[] args) { Thread t = Thread.currentThread(); // получаем главный поток System.out.println(t); // main }
Консольный вывод:
Thread
Первое будет представлять имя потока (что можно получить через ), второе значение 5 предоставляет приоритет
потока (также можно получить через ), и последнее представляет имя группы потоков, к которому относится текущий — по умолчанию также main
(также можно получить через )
Недостатки при использовании потоков
Далее мы рассмотрим, как создавать и использовать потоки. Это довольно легко. Однако при создании многопоточного приложения нам следует учитывать ряд обстоятельств,
которые негативно могут сказаться на работе приложения.
На некоторых платформах запуск новых потоков может замедлить работу приложения. Что может иметь большое значение, если нам критичная производительность
приложения.
Для каждого потока создается свой собственный стек в памяти, куда помещаются все локальные переменные и ряд других данных, связанных с выполнением
потока. Соответственно, чем больше потоков создается, тем больше памяти используется. При этом надо помнить, в любой системе размеры используемой памяти ограничены.
Кроме того, во многих системах может быть ограничение на количество потоков. Но даже если такого ограничения нет, то в любом случае
имеется естественное ограничение в виде максимальной скорости процессора.
НазадВперед
Возведение в степень
Возвести число в степень можно двумя способами:
- простое умножение;
- используя метод (двойное основание, двойной показатель степени).
Использование библиотечной функции рекомендуется только в случае крайней необходимости, например, в случае дробной или отрицательной степени.
Простое умножение в Java работает в 300-600 раз эффективнее, кроме того, его можно дополнительно оптимизировать:
JIT оптимизация
Код Java обрабатывается с использованием JIT-компиляции: сначала он транслируется в платформенно-независимый байт-код, а затем в машинный код. При этом оптимизируется все возможное, и разработчик может помочь компилятору создать максимально эффективную программу.
В качестве примера рассмотрим две простые операции:
Давайте измерим время выполнения каждого из них:
Запустив этот код несколько раз, мы получим примерно следующее:
Схема очевидна: группировка переменных в круглые скобки ускоряет работу программы. Это связано с генерацией более эффективного байт-кода при умножении одинаковых значений.
Вы можете узнать больше об этом эксперименте здесь. Или можете провести свой собственный тест, используя онлайн-компилятор Java.
Класс Object и его методы
Последнее обновление: 21.04.2018
Хотя мы можем создать обычный класс, который не является наследником, но фактически все классы наследуются от класса Object.
Все остальные классы, даже те, которые мы добавляем в свой проект, являются неявно производными от класса Object.
Поэтому все типы и классы могут реализовать те методы, которые определены в классе Object. Рассмотрим эти методы.
toString
Метод служит для получения представления данного объекта в виде строки. При попытке вывести строковое представления
какого-нибудь объекта, как правило, будет выводиться полное имя класса. Например:
public class Program{ public static void main(String[] args) { Person tom = new Person("Tom"); System.out.println(tom.toString()); // Будет выводить что-то наподобие Person@7960847b } } class Person { private String name; public Person(String name){ this.name=name; } }
Полученное мной значение (в данном случае ) вряд ли может служить хорошим строковым описанием объекта.
Поэтому метод нередко переопределяют. Например:
public class Program{ public static void main(String[] args) { Person tom = new Person("Tom"); System.out.println(tom.toString()); // Person Tom } } class Person { private String name; public Person(String name){ this.name=name; } @Override public String toString(){ return "Person " + name; } }
Метод hashCode
Метод hashCode позволяет задать некоторое числовое значение, которое будет соответствовать данному объекту или его хэш-код.
По данному числу, например, можно сравнивать объекты.
Например, выведем представление вышеопределенного объекта:
Person tom = new Person("Tom"); System.out.println(tom.hashCode()); // 2036368507
Но мы можем задать свой алгоритм определения хэш-кода объекта:
class Person { private String name; public Person(String name){ this.name=name; } @Override public int hashCode(){ return 10 * name.hashCode() + 20456; } }
Получение типа объекта и метод getClass
Метод позволяет получить тип данного объекта:
Person tom = new Person("Tom"); System.out.println(tom.getClass()); // class Person
Метод equals
Метод equals сравнивает два объекта на равенство:
public class Program{ public static void main(String[] args) { Person tom = new Person("Tom"); Person bob = new Person("Bob"); System.out.println(tom.equals(bob)); // false Person tom2 = new Person("Tom"); System.out.println(tom.equals(tom2)); // true } } class Person { private String name; public Person(String name){ this.name=name; } @Override public boolean equals(Object obj){ if (!(obj instanceof Person)) return false; Person p = (Person)obj; return this.name.equals(p.name); } }
Метод equals принимает в качестве параметра объект любого типа, который мы затем приводим к текущему, если они являются объектами
одного класса.
Оператор instanceof позволяет выяснить, является ли переданный в качестве параметра объект объектом определенного класса,
в данном случае класса Person. Если объекты принадлежат к разным классам, то их сравнение не имеет смысла, и возвращается значение false.
Затем сравниваем по именам. Если они совпадают, возвращаем true, что будет говорить, что объекты равны.
НазадВперед
3 Создание подстрок
Кроме сравнения строк и поиска подстрок, есть еще одно очень популярное действие — получение подстроки из строки. В предыдущем примере вы как раз видели вызов метода , который возвращал часть строки.
Вот список из 8 методов получения подстрок из текущей строки:
Методы | Описание |
---|---|
Возвращает подстроку, заданную интервалом символов . | |
Повторяет текущую строку n раз | |
Возвращает новую строку: заменяет символ на символ | |
Заменяет в текущей строке подстроку, заданную регулярным выражением. | |
Заменяет в текущей строке все подстроки, совпадающие с регулярным выражением. | |
Преобразует строку к нижнему регистру | |
Преобразует строку к верхнему регистру | |
Удаляет все пробелы в начале и конце строки |
Вот краткое описание существующих методов:
Метод
Метод возвращает новую строку, которая состоит из символов текущей строки, начиная с символа под номером и заканчивая . Как и во всех интервалах в Java, символ с номером в интервал не входит. Примеры:
Код | Результат |
---|---|
Если параметр не указывается (а так можно), подстрока берется от символа beginIndex и до конца строки.
Метод
Метод repeat просто повторяет текущую строку раз. Пример:
Код | Результат |
---|---|
Метод
Метод возвращает новую строку, в которой все символы заменены на символ . Длина строки при этом не меняется. Пример:
Код | Результат |
---|---|
Методы и
Метод заменяет все вхождения одной подстроки на другую. Метод заменяет первое вхождение переданной подстроки на заданную подстроку. Строка, которую заменяют, задается регулярным выражением. Разбирать регулярные выражения мы будем в квесте Java Multithreading.
Примеры:
Код | Результат |
---|---|
Методы
С этими методами мы познакомились, когда только в первый раз учились вызывать методы класса .
Метод
Метод удаляет у строки пробелы с начала и с конца строки. Пробелы внутри строки никто не трогает. Примеры:
Код | Результат |
---|---|
All String Methods
The String class has a set of built-in methods that you can use on strings.
Method | Description | Return Type |
---|---|---|
charAt() | Returns the character at the specified index (position) | char |
codePointAt() | Returns the Unicode of the character at the specified index | int |
codePointBefore() | Returns the Unicode of the character before the specified index | int |
codePointCount() | Returns the Unicode in the specified text range of this String | int |
compareTo() | Compares two strings lexicographically | int |
compareToIgnoreCase() | Compares two strings lexicographically, ignoring case differences | int |
concat() | Appends a string to the end of another string | String |
contains() | Checks whether a string contains a sequence of characters | boolean |
contentEquals() | Checks whether a string contains the exact same sequence of characters of the specified CharSequence or StringBuffer |
boolean |
copyValueOf() | Returns a String that represents the characters of the character array | String |
endsWith() | Checks whether a string ends with the specified character(s) | boolean |
equals() | Compares two strings. Returns true if the strings are equal, and false if not |
boolean |
equalsIgnoreCase() | Compares two strings, ignoring case considerations | boolean |
format() | Returns a formatted string using the specified locale, format string, and arguments | String |
getBytes() | Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array | byte[] |
getChars() | Copies characters from a string to an array of chars | void |
hashCode() | Returns the hash code of a string | int |
indexOf() | Returns the position of the first found occurrence of specified characters in a string | int |
intern() | Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index | String |
isEmpty() | Checks whether a string is empty or not | boolean |
lastIndexOf() | Returns the position of the last found occurrence of specified characters in a string | int |
length() | Returns the length of a specified string | int |
matches() | Searches a string for a match against a regular expression, and returns the matches | boolean |
offsetByCodePoints() | Returns the index within this String that is offset from the given index by codePointOffset code points | int |
regionMatches() | Tests if two string regions are equal | boolean |
replace() | Searches a string for a specified value, and returns a new string where the specified values are replaced | String |
replaceFirst() | Replaces the first occurrence of a substring that matches the given regular expression with the given replacement | String |
replaceAll() | Replaces each substring of this string that matches the given regular expression with the given replacement | String |
split() | Splits a string into an array of substrings | String[] |
startsWith() | Checks whether a string starts with specified characters | boolean |
subSequence() | Returns a new character sequence that is a subsequence of this sequence | CharSequence |
substring() | Extracts the characters from a string, beginning at a specified start position, and through the specified number of character | String |
toCharArray() | Converts this string to a new character array | char[] |
toLowerCase() | Converts a string to lower case letters | String |
toString() | Returns the value of a String object | String |
toUpperCase() | Converts a string to upper case letters | String |
trim() | Removes whitespace from both ends of a string | String |
valueOf() | Returns the primitive value of a String object | String |
❮ Previous
Next ❯
Creating Strings
The most direct way to create a string is to write −
String greeting = "Hello world!";
Whenever it encounters a string literal in your code, the compiler creates a String object with its value in this case, «Hello world!’.
As with any other object, you can create String objects by using the new keyword and a constructor. The String class has 11 constructors that allow you to provide the initial value of the string using different sources, such as an array of characters.
Example
public class StringDemo { public static void main(String args[]) { char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' }; String helloString = new String(helloArray); System.out.println( helloString ); } }
This will produce the following result −
Output
hello.
Note − The String class is immutable, so that once it is created a String object cannot be changed. If there is a necessity to make a lot of modifications to Strings of characters, then you should use String Buffer & String Builder Classes.