Класс string

Алан-э-Дейл       11.03.2024 г.

Замена содержимого строки

Метод заменяет указанное значение с другим значением в строке:

Пример

str = «Пожалуйста, посетите Microsoft!»;
var n = str.replace(«Microsoft», «Schoolsw3»);

Метод не изменяет строку она вызвана. Он возвращает новую строку.

По умолчанию метод заменяет только первое совпадение:

Пример

str = «Пожалуйста, посетите Microsoft и Microsoft!»;
var n = str.replace(«Microsoft», «Schoolsw3»);

По умолчанию метод чувствителен к регистру.
Записать MICROSOFT (в верхнем регистре) не получится:

Пример

str = «Пожалуйста, посетите Microsoft!»;
var n = str.replace(«MICROSOFT», «Schoolsw3»);

Чтобы заменить нечувствительность к регистру, используйте регулярное выражение
с флагом (нечувствительность):

Пример

str = «Пожалуйста, посетите Microsoft!»;
var n = str.replace(/MICROSOFT/i, «Schoolsw3»);

Обратите внимание, что регулярные выражения пишутся без кавычек. Чтобы заменить все совпадения, используйте регулярное выражение
с флагом (глобальное совпадение):

Чтобы заменить все совпадения, используйте регулярное выражение
с флагом (глобальное совпадение):

Пример

str = «Пожалуйста, посетите Microsoft и Microsoft!»;
var n = str.replace(/Microsoft/g, «Schoolsw3»);

Вы узнаете намного больше о регулярных выражениях в главе Регулярные выражения JavaScript.

Сравниваем строки в Java

Мы уже писали о том, как сравнивать строки в Java, используя для этого метод equals() (регистр учитывается) и equalsIgnoreCase() (регистр не учитывается). Хотелось бы сказать пару слов про ещё одну пару методов: int compareTo(String str) и int compareToIgnoreCase(String str) — они позволяют не только сравнить 2 строки, но и узнать, больше ли одна другой. Если значение, которое возвращается, больше 0, первая строка больше, если меньше нуля, всё наоборот. Когда обе строки равны, вернётся ноль.

Для определения используется лексикографический порядок. Допустим, строка «A» меньше строки «B», ведь символ ‘A’ в алфавите находится перед символом ‘B’. Когда первые символы строк равны, в расчёт берутся следующие символы. К примеру:

String str1 = "hello";
String str2 = "world";
String str3 = "hell";

System.out.println(str1.compareTo(str2)); // -15 - str1 меньше, чем strt2
System.out.println(str1.compareTo(str3)); // 1 - str1 больше, чем str3

Метод concat()

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

Его синтаксис выглядит вот так — string1.concat(string2). Результатом выполнения будет строка, получившаяся от соединения двух исходных. Применять метод не обязательно к объекту типа String. Можно использовать concat и таким образом: «Привет, ».concat(«мир!»). Однако, на практике, чаще всего используют оператор «+», который обладает тем же функционалом. Пример: «Привет, » + «мир!».

String Concatenation:

Concatenation is joining of two or more strings.

Have a look at the below picture-

We have two strings str1 = “Rock” and str2 = “Star”

If we add up these two strings, we should have a result as str3= “RockStar”.

Check the below code snippet,and it explains the two methods to perform string concatenation.

First is using “concat” method of String class and second is using arithmetic “+” operator. Both results in the same output

public class Sample_String{
  public static void main(String[] args){
//String Concatenation
String str1 = "Rock";
String str2 = "Star";
//Method 1 : Using concat
String str3 = str1.concat(str2);
System.out.println(str3);
//Method 2 : Using "+" operator
String str4 = str1 + str2;
System.out.println(str4);
}
}

LinkedList to String

Let’s convert LinkedList to String using String.join() method.

In case of any issues during conversion, we can notice the error message in the console log.

To conclude, in this tutorial we gone through different ways to convert a Java List to String data type.

List to String methods conversion is also common in other programming languages like JavaScript, Python, Jquery.

In a nutshell, JavaScript uses an str function for concatenate, likewise, the python program uses join method for conversion and concatenate a string.

Interested to read JavaScript resources, check out this JavaScript split method article.

Keeping sharing java tutorials and happy coding

Оптимальный порядок слияния

С отдельными слияниями разобрались, но что с сортировкой в целом? Первое, что стоит сделать, это улучшить случай отсортированного массива. Для этого необходимо не просто разрезать массив на подмассивы одинаковой длинны \(2^j\), а выбирать максимально длинные отсортированные части. Кроме того можно выбирать не только подмассивы, отсортированные в нужном нам порядке, но и обратно отсортированные, меняя для них направление итератора. Таким образом можно получить список подмассивов оригинального массива, для каждого подмассива необходима пара чисел: начало и конец. При этом, если начало больше конца, значит подмассив обратно отсортирован.

И тут возникает следующий вопрос: в каком порядке сливать полученные подмассивы? Для того, чтобы более наглядно фиксировать порядок слияния, будем использовать дерево слияния.

graph TD
ABCD
ABCD—AB
AB—A
AB—B
ABCD—CD
CD—C
CD—D
style A fill:LightCoral
style B fill:SpringGreen
style C fill:SkyBlue
style D fill:MediumPurple
style AB fill:Yellow
style CD fill:Cyan
style ABCD fill:White

Рис. 1.

Ниже в узлах дерева будем записывать только размеры подмассивов.

graph TD
ABCD((24))
ABCD—AB((18))
AB—A((2))
AB—B((16))
ABCD—CD((6))
CD—C((3))
CD—D((3))
style A fill:LightCoral
style B fill:SpringGreen
style C fill:SkyBlue
style D fill:MediumPurple
style AB fill:Yellow
style CD fill:Cyan
style ABCD fill:White

Рис. 2.

В данном случае это минимальное по глубине дерево. Такое дерево легко получить при обработке подмассивов в порядке расположения. Однако, это не всегда выигрышный подход, как и в этом примере. Надо помнить, что сложность функции слияния зависит от размеров сливаемых частей. И это дерево не является оптимальным, потому что самый большой подмассив, состоящий из \(16\) элементов мы сливали дважды. Более оптимальным в данном случае будет следующее дерево слияния:

graph TD
ABCD((24))
ABCD—ACD((8))
ACD—AC((5))
AC—A((2))
AC—C((3))
ACD—D((3))
ABCD—B((16))
style A fill:LightCoral
style B fill:SpringGreen
style C fill:SkyBlue
style D fill:MediumPurple
style AC fill:#b666d2
style ACD fill:#df00ff
style ABCD fill:White

Рис. 3.

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

Лемма

Пусть \(X = ( x_i \colon i < k )\) конечная последовательность натуральных чисел. Будем строить последовательность \(Y\) следующим образом:

  • выберем и вычеркнем из \(X \cup Y\) два минимальных числа \(a\) и \(b\);
  • добавим в \(Y\) число \(a + b\);
  • повторяем до тех пор, пока \(|X \cup Y| \geqslant 2\).

Тогда на каждом шаге \(a + b \geqslant \max Y\).

Доказательство достаточно тривиально и оставляется на откуп читателю ().

Куда труднее эту лемму применить. Для оптимального слияния необходимо правильно расположить начальные подмассивы друг относительно друга так, чтобы всегда сливались соседние. Расположить подмассивы просто в порядке возрастания их длин неверное решение, например, если у нас есть подмассивы длин \((1, 2, 2, 2, 3)\), то последний подмассив надо перенести в середину:

graph TD
ABCDE((10))
ABCDE—ABE((6))
ABE—AB((3))
AB—A((1))
AB—B((2))
ABCDE—CD((4))
CD—C((2))
CD—D((2))
ABE—E((3))
style E fill:pink

Рис. 4.

Релизация подобной перестановки оставляется читателю.

Пример

программа, которая была перечислена в разделе, названном «Строки», является примером программы, которая была бы более эффективной если a использовались вместо a .

инвертированный палиндром. Здесь, еще раз, его перечисление:


public class StringDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";
        int len = palindrome.length();
        char[] tempCharArray = new char;
        char[] charArray = new char;
        
        // put original string in an 
        // array of chars
        for (int i = 0; i < len; i++) {
            tempCharArray = 
                palindrome.charAt(i);
        } 
        
        // reverse array of chars
        for (int j = 0; j < len; j++) {
            charArray =
                tempCharArray;
        }
        
        String reversePalindrome =
            new String(charArray);
        System.out.println(reversePalindrome);
    }
}

Выполнение программы производит этот вывод:

doT saw I was toD

Чтобы выполнить строковое реверсирование, программа преобразовывает строку в массив символов (сначала цикл), инвертирует массив во второй массив (второй цикл), и затем преобразовывает назад в строку.

Если Вы преобразовываете представьте в виде строки строковому разработчику, можно использовать метод в class. Это делает код более простым и легче читать:


public class StringBuilderDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";
         
        StringBuilder sb = new StringBuilder(palindrome);
        
        sb.reverse();  // reverse it
        
        System.out.println(sb);
    }
}

Выполнение этой программы производит тот же самый вывод:

doT saw I was toD

Отметьте это печатает строкового разработчика, как в:

System.out.println(sb);

потому что вызывается неявно, как это с любым другим объектом в a вызов.

Отметьте: есть также a class, который является точно тем же самым как class, за исключением того, что это ориентировано на многопотоковое исполнение на основании синхронизации его методов. Потоки будут обсуждены в уроке на параллелизме.

Загрузка классов

Теперь, разобравшись с общей структурой файла, посмотрим, как JVM его обрабатывает.

Чтобы попасть в JVM, класс должен быть загружен. Для этого существуют специальные классы-загрузчики:

  1. Bootstrap — базовый загрузчик, загружает платформенные классы. Этот загрузчик является родителем всех остальных классов и частью платформы.
  2. Extension ClassLoader — загрузчик расширений, потомок Bootstrap-загрузчика. Загружает классы расширений, которые по умолчанию находятся в каталоге .
  3. AppClassLoader — системный загрузчик классов из classpath, который является непосредственным потомком Extension ClassLoader. Он загружает классы из каталогов и jar-файлов, указанных переменной среды , системным свойством или параметром командной строки .
  4. Собственный загрузчик — у приложения могут быть свои собственные загрузчики.

Главный класс приложения всегда загружается системным загрузчиком, остальные же классы могут быть загружены различными пользовательскими загрузчиками. Стоит упомянуть, что имя загрузчика создаёт уникальное пространство имён, то есть в программе может существовать несколько классов с одним и тем же полным именем, если они обрабатывались разными загрузчиками.
Поэтому каждый загрузчик делегирует свои полномочия родителю, то есть перед поиском класса для загрузки он попытается узнать, не был ли загружен нужный класс раньше.

После загрузки класса начинается этап линковки, который делится на три части.

  1. Верификация байт-кода. Это статический анализ кода, выполняется один раз для класса. Система проверяет, нет ли ошибок в байт-коде. Например, проверяет корректность инструкций, переполнение стека и совместимость типов переменных.
  2. Выделение памяти под статические поля и их инициализация.
  3. Разрешение символьных ссылок — JVM подставляет ссылки на другие классы, методы и поля. В большинстве случаев это происходит лениво, то есть при первом обращении к классу.

Класс инициализируется, и JVM может начать выполнение байт-кода методов.

JVM получает один поток байтовых кодов для каждого метода в классе. Байт-код метода выполняется, когда этот метод вызывается в ходе работы программы. Поток байт-кода метода — это последовательность инструкций для виртуальной машины Java. Каждая инструкция состоит из однобайтового кода операции, за которым может следовать несколько операндов. Код операции указывает действие, которое нужно предпринять. Всего на данный момент в Java более 200 операций. Все коды операций занимают только 1 байт, так как они были разработаны компактными, поэтому их максимальное число не может превысить 256 штук.

В основе работы JVM находится стек — основные инструкции работают с ним.

Рассмотрим пример умножения двух чисел. Ниже представлен байт-код метода:

На Java это будет выглядеть так:

По листингу выше можно заметить, что коды операций сами по себе указывают тип и значение. Например, код операции указывает JVM на целочисленное значение, равное единице. Такие байт-коды определены для самых часто используемых констант. Эти инструкции занимают 1 байт и введены специально для повышения эффективности выполнения байт-кода и уменьшения размера его потока. Подобные короткие константы также присутствуют и для других типов данных.

Всего JVM поддерживает семь примитивных типов данных: byte, short, int, long, float, double и char.

Если бы мы хотели положить в переменную а другое значение, например 11112, то нам пришлось бы использовать инструкцию :

Данные операции выполняются в так называемом фрейме стека метода. У каждого метода есть некоторая своя часть в общем стеке. Таким образом в нашем главном потоке исполнения программы создаются множество подстеков на каждый вызов метода. Более наглядно это представлено на картинке ниже:

В каждом стек-фрейме хранится массив локальных переменных, который позволяет сохранять и доставать локальные переменные, как мы сделали в примере выше, поместив значения 1 и 5 в переменные 1 и 2. Стоить отметить, что здесь компилятор также оптимизировал байт-код, используя однобайтовые инструкции. Если бы переменных в нашем методе было много, использовался бы код операции сохранения значения вместе с указанием позиции переменной в массиве.

Чтобы достучаться до пула констант класса и получить нужное значение, используются инструкции и . При этом может ссылаться только на константы с индексами от 1 до 255, поскольку размер её операнда составляет всего 1 байт. имеет 2-байтовый индекс, поэтому может ссылаться на более широкий диапазон индексов.

Массив строк и массив указателей

Рассмотрим более сложный пример. Допустим, у нас есть набор строк. Требуется выполнить сортировку строк по возрастанию по признаку длины: сначала вывести самые короткие строки, затем более длинные.

Набор строк можно представить как двумерный массив, т.е. массив, состоящий из одномерных массивов, где каждый одномерный массив — это строка символов:

char str10 = {"Hello", "World", 
                  "!!!", "&&&"};

Представьте себе, что значит выполнить сортировку строк. Это значит, надо поменять местами содержимое множества ячеек памяти. Это достаточно трудоемкая для компьютера работа, особенно если строк очень много. Однако можно поступить по-иному. Достаточно создать массив указателей, каждый элемент которого будет указывать на соответствующую ему строку первого массива. Далее выполнить сортировку указателей, что несомненно быстрее. Конечно, сам массив строк отсортирован не будет, однако благодаря указателям у нас будет хранится отсортированный «срез» массива:

#include <stdio.h>
#include <string.h>
 
#define N 6
 
void sortlen(char *s);
 
int main() {
    char stringsN30;
    char *strPN;
    int i;
 
    for(i=; i<N; i++) {
        gets(stringsi);
        strPi = &stringsi;
    }
    printf("\n");
 
    sortlen(strP);
 
    for(i=; i<N; i++) {
        printf("%s\n",strPi);
    }
 
}
 
// **s == *s[] - массив указателей
void sortlen(char **s) { 
    int i, j;
    char *str;
 
    for (i=; i<N-1; i++)
        for (j=; j < N-i-1; j++)
          if (strlen(sj)>strlen(sj+1)){
              str = sj;
              sj = sj+1;
              sj+1 = str;
          }             
}

Примечания к программе:

  • На самом деле параметром функции является указатель на указатель. Хотя для понимания проще сказать, что параметром является массив указателей на символы. Мы передаем в функцию указатель на первый элемент массива strP, который сам является указателем. Если бы в функции мы инкрементировали переменную s, то переходили бы к следующему элементу-указателю массива strP.
  • Сортировка выполняется методом пузырька: если длина строки, на которую ссылается следующий указатель массива strP, меньше длины строки под текущим указателем, то значения указателей меняются.
  • Выражение strP = &strings означает, что элементу массива указателей присваивается ссылка на первый символ каждой строки.

Напишите программу, которая сортирует строки по алфавиту. Для упрощения задачи пусть сортировка выполняется только по первым буквам строк (если первые буквы слов одинаковы, то вторые и последующие символы проверять не надо).

Немного о преобразованиях

В процессе программирования неотъемлемо происходят различные преобразования одних типов в другие. Например, может понадобиться получить из строки число для обработки его какой-либо операцией. Это очень распространённое приведение в Java String to int. На практике это выглядит так:

int переменная = Integer.parseInt(Объект_типа_String). Приведение в Java String to int может порождать и исключения. Например, когда в преобразуемой к числу строке,содержатся не только цифры, но и буквы. Естественно, что такое исключение нужно вовремя перехватить и обработать.

Существует и второй тип преобразования строки в число — Integer.valueOf(). Единственная разница между ними состоит в том, что parseInt возвращает примитивный int, а valueOf — объект типа Integer.

Массивы и перечисления очень активно используются при программировании в Java. String array — это совокупность данных, объединённых по общему признаку. Преобразовать строку массив символов очень просто — для этого используется метод toCharArray(). Он разбивает текстовые данные посимвольно и создаёт список с ними. Тип массива при этом будет char[].

Методы String Java могут выполнять и обратное преобразование. К примеру, когда нужно представить число или другой тип данных как строку. Выглядит применение так:

String.valueOf(значение_или_переменная одного из нескольких типов). Результатом выполнения будет строка.

Formatting an Integer

With the format specifier, you can use an argument of all integral types including byte, short, int, long and BigInteger.

(Negative numbers always have the “-” included):

String.format("|%+20d|', 93);
// prints: |                 +93|
A space before positive numbers.

A “-” is included for negative numbers as per normal.

String.format("|% d|", 93);
// prints: | 93|

String.format("|% d|", -36);
// prints: |-36|

For the US locale, it is “,”:

String.format("|%,d|", 10000000);
// prints: |10,000,000|

Prints octal numbers with a leading “” and hex numbers with leading ““.

String.format("|%#o|", 93);
// prints: 0135

String.format("|%#x|", 93);
// prints: 0x5d

String.format("|%#X|", 93);
// prints: 0X5D

Using String.chars() method

Java 8 provides a new method, , which returns an (a stream of ints) representing an integer representation of characters in the String. This method does not return the desired (for performance reasons), but we can map to an object in such a way that it will automatically box into a . There are various ways to achieve that, as shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

classMain

{

// Iterate over the characters of a string

publicstaticvoidmain(Stringargs)

{

Strings=»Techie Delight»;

// 1. Implicit boxing into `Stream<Character>`

// 1.1. Using method reference

s.chars()

.mapToObj(Character::toChars)

.forEach(System.out::print);

// 1.2. Using lambda expressions by casting `int` to `char`

s.chars()

.mapToObj(i->Character.valueOf((char)i))

.forEach(System.out::print);

s.chars()

.mapToObj(i->(char)i)

.forEach(System.out::print);

s.chars()

.mapToObj(i->newStringBuilder().appendCodePoint(i))

.forEach(System.out::print);

// 2. Without boxing into `Stream<Character>`

s.chars()

.forEach(i->System.out.print(Character.toChars(i)));

s.chars()

.forEach(i->System.out.print((char)i));

s.chars()

.forEach(i->System.out.print(newStringBuilder()

.appendCodePoint(i)));

}

}

Download  Run Code

Important Points to Note:

  • String is a Final class; i.e once created the value cannot be altered. Thus String objects are called immutable.
  • The Java Virtual Machine(JVM) creates a memory location especially for Strings called String Constant Pool. That’s why String can be initialized without ‘new’ keyword.
  • String class falls under java.lang.String hierarchy. But there is no need to import this class. Java platform provides them automatically.
  • String reference can be overridden but that does not delete the content; i.e., if

String h1 = “hello”;

h1 = “hello”+”world”;

then “hello” String does not get deleted. It just loses its handle.

Multiple references can be used for same String but it will occur in the same place; i.e., if

String h1 = “hello”;

String h2 = “hello”;

String h3 = “hello”;

then only one pool for String “hello” is created in the memory with 3 references-h1,h2,h3

If a number is quoted in ” “ then it becomes a string, not a number anymore. That means if

String S1 =”The number is: “+ “123”+”456″;

System.out.println(S1);

then it will print: The number is: 123456

If the initialization is like this:

String S1 = “The number is: “+(123+456);

System.out.println(S1);

then it will print: The number is:579

That’s all to Strings!

Objects equals

The Objects equals method invokes the overridden String equals method; its behavior is the same as in the String equals example above.

String string1 = "MYTEXT";String string2 = "YOURTEXT";System.out.println("Output: " + Objects(string1, string2));
Output false
String string1 = "MYTEXT";String string3 = "mytext";System.out.println("Output: " + Objects(string1, string3));
Output false
String string1 = "MYTEXT";String string6 = "MYTEXT";System.out.println("Output: " + Objects(string1, string6));
Output true
String string1 = "MYTEXT";String string8 = null;System.out.println("Output: " + Objects.equals(string1, string8));
Output falseSystem.out.println("Output: " + Objects.equals(string8, string1));
Output false
String string8 = null;String string9 = null;System.out.println("Output: " + Objects.equals(string8, string9)); 
Output true

The advantage here is that the Objects equals method checks for null values (unlike String equals). The implementation of Object equals is:

public static boolean equals(Object a, Object b) {return (a == b) || (a != null && a.equals(b));}

Collector

The interface defines a set of methods which are used
during the reduction process. The following is the interface signature with the
five methods it declares.

public interface Collector<T,A,R> {
    Supplier<A> supplier();
    BiConsumer<A,T> accumulator();
    BinaryOperator<A> combiner();
    Function<A,R> finisher();
    Set<Characteristics> characteristics();
}

A is specified by four functions that work together to
accumulate entries into a mutable result container, and optionally perform a
final transform on the result.

The is the type of elements in the stream to be collected.
The the type of the accumulator. The is the type
of the result returned by the collector.

The supplier returns a function which creates a new result container.
The accumulator returns a function which performs the reduction
operation. It accepts two arguments: the first ist the mutable result container
(accumulator) and the second the stream element that is folded into the result
container.

When the stream is collected in parallel the combiner returns a
function which merges two accumulators. The finisher returns a function
which performs the final transformation from the intermediate result container
to the final result of type . The finisher returns an identity
function when the accumulator already represents the final result.

Note: In math, the identity function is one in which the output
of the function is equal to its input. In Java, the method
of a returns a that always returns
its input arguments.

The method returns an immutable set of
which define the behavior of the collector. It can
be used to do some optimizations during the reduction process. For example, if
the set contains , then the collection process can be
performed in parallel.

Метод format()

Для придания получившихся в итоге выполнения программы готовых строк используется метод String.format. Java обзавелась этим решением, начиная с 5 версии.

Иногда нужно вывести не только строки на экран, а результаты числовых расчетов. И не всегда они соответствуют ожидаемому представлению. Например, некоторые значения могут иметь ряд символов после запятой или формат даты может быть в непривычном для страны виде. Это особенно актуально при разработке больших финансовых комплексов, в которых выводится множество различных данных о передвижении денежных средств и материалов.

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

Разбиение строки на подстроки

Метод split()
позволяет разбить строку на подстроки по определенному разделителю. Разделитель
– это какой-нибудь символ или набор символов (передается в качестве параметра).
Например, разобьем текст на отдельные слова (учитывая, что слова разделены
пробелом):

String text = "Я люблю язык Java!";
String words = text.split(" ");
 
for(String word  words)
    System.out.println(word);

Видео по теме

#1 Установка пакетов и первый запуск программы

#2 Структура программы, переменные, константы, оператор присваивания

#3 Консольный ввод/вывод, импорт пакетов

#4 Арифметические операции

#5 Условные операторы if и switch

#6 Операторы циклов while, for, do while

#7 Массивы, обработка элементов массива

#8 (часть 1) Строки в Java, методы класса String

#8 (часть 2) Строки — классы StringBuffer и StringBuider

#9 Битовые операции И, ИЛИ, НЕ, XOR

#10 Методы, их перегрузка и рекурсия

Цели проектирования (почему String должен быть неизменным)

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

1. Потребность в пуле постоянных времени выполнения

При выполнении приведенного выше кода JVM сначала проверяет, есть ли объект String «abc» в пуле констант времени выполнения. Если объект уже существует, ему не нужно создавать новый объект String «abc», но он указывает ссылку s непосредственно на пул констант времени выполнения. Существующий объект String «abc» в; если он не существует, сначала создайте новый объект String «abc» в пуле констант времени выполнения, а затем укажите ссылку s на новый объект String, созданный в пуле констант времени выполнения.

Когда приведенный выше код выполняется, только один объект String «abc» создается в пуле констант времени выполнения, что экономит место в памяти.Принципиальная схема выглядит следующим образом:

2. Синхронизация

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

3. Разрешить объектам String кэшировать хэш-код.

Глядя на исходный код класса String в JDK1.8 выше, вы можете обнаружить, что существует хэш поля. Неизменяемость класса String гарантирует уникальность хэш-кода, поэтому хеш-код объекта String можно кэшировать с помощью хэш-поля. Рассчитайте хэш-код. Поэтому объекты String в Java часто используются в качестве ключей контейнеров, таких как HashMap.

4. Безопасность

Если объект String является изменяемым, это вызовет серьезные проблемы с безопасностью. Например, имя пользователя и пароль базы данных передаются в виде строк для получения соединения с базой данных или при программировании сокетов имя хоста и порт передаются в виде строк. Поскольку объект String неизменяем, его значение нельзя изменить.В противном случае хакеры могут воспользоваться лазейкой и изменить значение объекта, на который указывает ссылка на String, что вызовет бреши в безопасности.

String equalsIgnoreCase

Метод equalsIgnoreCase() осуществляет Java сравнение строк лексикографически, игнорируя различия регистра. Значение true возвращается только тогда, когда аргумент является объектом String, который представляет ту же последовательность символов, что и объект. Если нужно проверить строки на равенство без учета регистра, лучше использовать метод equalsIgnoreCase класса String.

Пример

class TestClass{
  public static void main (String[] args){
    String str1 = "Java";
    String str2 = "JAVA";
    // возвращает true, потому что оба равны без учета регистра
    if(str1.equalsIgnoreCase(str2)){
      System.out.println("Statement  is true");
    }else{
      System.out.println("Statement is false");
    }
    // возвращает false при чувствительности к регистру
    if(str1.equals(str2)){
      System.out.println("Statement  is true");
    }else{
      System.out.println("Statement is false");
    }
  }
}

Результат

Statement  is true
Statement is false

Проверка на палиндромность

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

Замечание Если этот вопрос попадется вам на собеседовании, лучше спросить, чем считать пустую строку. Мы считаем ее палиндромом.

На самом деле, решение этой задачи не очень сложное имы предлагаем аж два варианта.

Сначала обработать строку

Для начала можно пройтись по строке, оставив только буквы и цифры, чего требует условие и лишь затем наивным способом проверить, является ли эта строка палиндромом, что потребует O(N) времени.

Сразу проверить строку

Другой вариант — проверка строки без обработки. В этом случае мы заводим два указателя, инициализируемые началом и концом строки. Далее они движутся по строке, смещаясь к центру, пока не станут указывать на букву или цифру. Затем просто проверяем их на равенство. Продолжаем выполнение, пока левый указатель не станет больше правого. Очевидно, что это те же O(N), но здесь меньше константа.

Оба эти решения приведены на programcreek.com.

Определение регулярных выражений

В JavaScript регулярные выражения представлены объектом , который является нативным объектом JavaScript, таким как , и так далее. Существует два способа создания нового объекта RegExp: один использует литеральный синтаксис, а другой — конструктор .

Литеральный синтаксис использует косую черту () для переноса шаблона регулярного выражения, тогда как синтаксис конструктора использует кавычки (). В следующем примере демонстрируются оба способа создания регулярного выражения, которое соответствует любой строке, начинающейся с «Mr.».

Как видите, литеральный синтаксис регулярного выражения короче и проще для чтения, поэтому предпочтительно использовать его. Мы также будем использовать его в этом уроке.

При использовании синтаксиса конструктора необходимо дважды экранировать специальные символы; это означает, что для поиска «.» вам нужно написать вместо . Если есть только один обратный слеш, он будет интерпретирован синтаксическим анализатором строк JavaScript как экранирующий символ и будет удален.

Way 5: Using append() method of StringBuffer & StringBuilder

  • This method can be used to convert primitive byte data-type to String object by appending to StringBuffer or StringBuilder object
  • And then invoking toString() method

Syntax:

StringBuffer sb = sb.append(byteValue);

String temp = sb.toString();

ConvertByteToStringByAppending.java

package in.bench.resources.bytes.to.string.conversion;

public class ConvertByteToStringByAppending {

	public static void main(String[] args) {

		// primitive byte data-type
		byte byteValue1 = 83;

		// 1. converting byte to String 
		// by using append() method
		StringBuffer sbf1 = new StringBuffer();
		String str1 = sbf1.append(byteValue1).toString();
		System.out.println("1. Converted"
				+ " primitive byte to String value is : "
				+ str1);


		// primitive byte data-type (negative value)
		byte byteValue2 = -33;

		// 2. converting negative byte to String 
		// by using append() method
		StringBuffer sbf2 = new StringBuffer();
		String str2 = sbf2.append(byteValue2).toString();
		System.out.println("\n2. Converted"
				+ " negative primitive byte to String value is : "
				+ str2);


		// Byte object
		Byte byteValue3 = new Byte((byte)93);

		// 3. converting Byte object to String 
		// by using append() method
		StringBuffer sbf3 = new StringBuffer();
		String str3 = sbf3.append(byteValue3).toString();
		System.out.println("\n3. Converted"
				+ " Byte object to String value is : "
				+ str3);
	}
}

Output:

1. Converted primitive byte to String value is : 83

2. Converted negative primitive byte to String value is : -33

3. Converted Byte object to String value is : 93
Гость форума
От: admin

Эта тема закрыта для публикации ответов.