logo

Stringi w Javie

W podanym przykładzie zostanie utworzony tylko jeden obiekt. Po pierwsze, JVM nie znajdzie żadnego obiektu string o wartości Welcome w puli stałych stringów, więc utworzy nowy obiekt. Następnie znajdzie w puli ciąg o wartości Welcome, nie utworzy nowego obiektu, ale zwróci referencję do tej samej instancji. W tym artykule dowiemy się o ciągach Java.

Co to są ciągi znaków w Javie?

Łańcuchy to typ obiektów, w których można przechowywać znaki wartości. W Javie każdy znak jest przechowywany na 16 bitach, tj. przy użyciu 16-bitowego kodowania UTF. Łańcuch działa tak samo jak tablica znaków w Javie.



Przykład:

String name = 'Geeks';>
Przykład ciągu w Javie

Przykład ciągu w Javie

Poniżej znajduje się przykład ciągu w Javie:



Jawa
// Java Program to demonstrate // String public class StringExample {  // Main Function  public static void main(String args[])  {  String str = new String('example');  // creating Java string by new keyword  // this statement create two object i.e  // first the object is created in heap  // memory area and second the object is  // created in String constant pool.  System.out.println(str);  } }>

Wyjście
example>

Sposoby tworzenia ciągu

Istnieją dwa sposoby tworzenia ciągu w Javie:

vlc, aby pobrać YouTube
  • Dosłowny ciąg
  • Używanie nowego słowa kluczowego

Składnia:

 = '';>

1. Dosłowny ciąg znaków

Aby zwiększyć wydajność pamięci Java (ponieważ nie są tworzone żadne nowe obiekty, jeśli istnieją już w puli stałych łańcuchów).



Przykład:

String demoString = techcodeview.com;>

2. Użycie nowego słowa kluczowego

  • String s = nowy String(Witamy);
  • W takim przypadku JVM utworzy nowy obiekt łańcuchowy w normalnej (innej niż pula) pamięci sterty, a dosłowne powitanie zostanie umieszczone w puli stałych łańcuchów. Zmienna s będzie odnosić się do obiektu na stercie (innego niż pula)

Przykład:

String demoString = new String (techcodeview.com);>

Interfejsy i klasy w ciągach znaków w Javie

CharBuffer : Ta klasa implementuje interfejs CharSequence. Ta klasa umożliwia używanie buforów znaków zamiast CharSequences. Przykładem takiego użycia jest pakiet wyrażeń regularnych java.util.regex.

Strunowy : Jest to ciąg znaków. W Javie obiekty String są niezmienne, co oznacza stałą i nie można ich zmienić po utworzeniu.

Interfejs CharSequence

Interfejs CharSequence służy do reprezentowania sekwencji znaków w Javie.
Klasy zaimplementowane przy użyciu interfejsu CharSequence są wymienione poniżej i zapewniają one wiele funkcji, takich jak podciąg, ostatnie wystąpienie, pierwsze wystąpienie, concatenate, toupper, tolower itp.

  1. Strunowy
  2. Bufor ciągów
  3. Konstruktor ciągów

1. Sznurek

String to niezmienna klasa, co oznacza stałą i nie można jej zmienić po utworzeniu, a jeśli chcemy to zmienić, musimy utworzyć nowy obiekt, a nawet funkcje, które zapewnia, takie jak toupper, tolower itp. Wszystkie one zwracają nowy obiekt, nie jest on modyfikowany oryginalny przedmiot. Jest automatycznie bezpieczny dla wątków.

Składnia

String str= 'geeks';  or String str= new String('geeks')>

2. Bufor ciągów

Bufor ciągów jest klasą równorzędną Strunowy , ma charakter zmienny i jest klasą bezpieczną dla wątków, możemy jej używać, gdy mamy środowisko wielowątkowe i współdzielony obiekt bufora łańcuchowego, tj. używany przez wiele wątków. Ponieważ jest bezpieczny dla wątków, powoduje dodatkowe obciążenie, dlatego jest używany głównie w programach wielowątkowych.

Składnia:

StringBuffer demoString = new StringBuffer('techcodeview.com');>

3. Kreator ciągów

Konstruktor ciągów w Javie stanowi alternatywę dla klas String i StringBuffer, ponieważ tworzy zmienną sekwencję znaków i nie jest bezpieczny dla wątków. Jest używany tylko w wątku, więc nie powoduje dodatkowych kosztów, więc jest używany głównie w programach jednowątkowych.

Składnia:

StringBuilder demoString = new StringBuilder(); demoString.append('GFG');>

StringTokenizer

StringTokenizer klasa w Javie służy do dzielenia ciągu na tokeny.

Przykład:

Tokenizator ciągów w Javie

Obiekt StringTokenizer wewnętrznie utrzymuje bieżącą pozycję w ciągu znaków, który ma być tokenizowany. Niektóre operacje przesuwają tę bieżącą pozycję poza przetworzone znaki. Token jest zwracany poprzez pobranie podciągu ciągu, który został użyty do utworzenia obiektu StringTokenizer.

StringJoiner jest klasą W java.util pakiet, który służy do konstruowania sekwencji znaków (ciągów) oddzielonych ogranicznikiem i opcjonalnie zaczynających się od podanego przedrostka i kończących się dostarczonym sufiksem. Chociaż można to również zrobić za pomocą klasy StringBuilder, aby dodać ogranicznik po każdym ciągu znaków, StringJoiner zapewnia łatwy sposób, aby to zrobić, bez konieczności pisania dużej ilości kodu.

Składnia:

public StringJoiner(CharSequence delimiter)>

Powyżej widzieliśmy, że możemy utworzyć ciąg znaków za pomocą String Literal.

String demoString =Witamy;

Tutaj JVM sprawdza pulę stałych ciągów. Jeśli ciąg nie istnieje, tworzona jest nowa instancja ciągu i umieszczana w puli. Jeśli ciąg istnieje, nie utworzy nowego obiektu. Zamiast tego zwróci odwołanie do tej samej instancji. Pamięć podręczna przechowująca te instancje ciągów jest nazywana pulą stałych ciągów lub pulą ciągów. We wcześniejszych wersjach Javy aż do puli JDK 6 String znajdowała się w przestrzeni PermGen (Permanent Generation). Ale w JDK 7 jest on przeniesiony do głównego obszaru sterty.

Niezmienny ciąg znaków w Javie

W Javie obiekty łańcuchowe są niezmienne. Niezmienny oznacza po prostu niemodyfikowalny lub niezmienny. Po utworzeniu obiektu tekstowego nie można zmienić jego danych ani stanu, lecz tworzony jest nowy obiekt łańcuchowy.

Poniżej realizacja tematu:

Jawa
// Java Program to demonstrate Immutable String in Java import java.io.*; class GFG {  public static void main(String[] args)  {  String s = 'Sachin';    // concat() method appends  // the string at the end  s.concat(' Tendulkar');    // This will print Sachin  // because strings are  // immutable objects  System.out.println(s);  } }>

Wyjście
Sachin>

Tutaj Sachin się nie zmienia, ale tworzony jest nowy obiekt z Sachinem Tendulkarem. Dlatego ciąg znaków nazywany jest niezmiennym.

Jak widać na podanym rysunku, utworzone zostały dwa obiekty, ale zmienna referencyjna nadal odnosi się do Sachina, a nie do Sachina Tendulkara. Ale jeśli jawnie przypiszemy ją do zmiennej referencyjnej, będzie ona odnosić się do obiektu Sachin Tendulkar.

Na przykład:

znak Java na ciąg
Jawa
// Java Program to demonstrate Explicitly assigned strings import java.io.*; class GFG {  public static void main(String[] args)  {  String name = 'Sachin';  name = name.concat(' Tendulkar');  System.out.println(name);  } }>

Wyjście
Sachin Tendulkar>

Przydział pamięci dla ciągu

Za każdym razem, gdy obiekt String jest tworzony jako literał, obiekt zostanie utworzony w puli stałej String. Dzięki temu JVM może zoptymalizować inicjalizację literału String.

Przykład:

String demoString = 'Geeks';>

Ciąg można również zadeklarować za pomocą a nowy operator, tj. przydzielany dynamicznie. W przypadku, gdy String jest przydzielany dynamicznie, przypisuje się mu nową lokalizację pamięci na stercie. Ten ciąg nie zostanie dodany do puli stałej String.

Przykład:

String demoString = new String('Geeks');>

Jeśli chcesz przechowywać ten ciąg w stałej puli, musisz go internować.

Przykład:

String internedString = demoString.intern();  // this will add the string to string constant pool.>

Preferowane jest używanie literałów String, ponieważ pozwala to JVM na optymalizację alokacji pamięci.

Przykład pokazujący, jak zadeklarować ciąg

Jawa
// Java code to illustrate String import java.io.*; import java.lang.*; class Test {  public static void main(String[] args)  {  // Declare String without using new operator  String name = 'techcodeview.com';  // Prints the String.  System.out.println('String name = ' + name);  // Declare String using new operator  String newString = new String('techcodeview.com');  // Prints the String.  System.out.println('String newString = ' + newString);  } }>

Wyjście
String name = techcodeview.com String newString = techcodeview.com>


Notatka: Obiekt String jest tworzony w obszarze sterty, a literały są przechowywane w specjalnym obszarze pamięci zwanym pulą stałych ciągów.

Dlaczego pula String została przeniesiona z PermGen do the normalny obszar sterty?

Przestrzeń PermGen jest ograniczona, domyślny rozmiar to zaledwie 64 MB. był to problem związany z tworzeniem i przechowywaniem zbyt wielu obiektów łańcuchowych w przestrzeni PermGen. Właśnie dlatego pulę String przeniesiono na większy obszar sterty. Aby zwiększyć efektywność pamięci Java, zastosowano koncepcję literału łańcuchowego. Używając słowa kluczowego „new”, maszyna JVM utworzy nowy obiekt łańcuchowy w normalnym obszarze sterty, nawet jeśli ten sam obiekt łańcuchowy znajduje się w puli ciągów.

Na przykład:

String demoString = new String('Bhubaneswar');>

Przyjrzyjmy się koncepcji z programem Java i zwizualizujmy rzeczywistą strukturę pamięci JVM:

Poniżej implementacja powyższego podejścia:

Jawa
// Java program and visualize the // actual JVM memory structure // mentioned in image class StringStorage {  public static void main(String args[])  {  // Declaring Strings  String s1 = 'TAT';  String s2 = 'TAT';  String s3 = new String('TAT');  String s4 = new String('TAT');  // Printing all the Strings  System.out.println(s1);  System.out.println(s2);  System.out.println(s3);  System.out.println(s4);  } }>

Wyjście
TAT TAT TAT TAT>
Pula ciągów w Javie

Pula ciągów w Javie

Notatka: Wszystkie obiekty w Javie są przechowywane na stercie. Zmienna referencyjna odnosi się do obiektu przechowywanego w obszarze stosu lub może być zawarta w innych obiektach, co umieszcza je również w obszarze sterty.

Przykład 1:

Jawa
// Construct String from subset of char array // Driver Class class GFG {  // main function  public static void main(String args[])  {  byte ascii[] = { 71, 70, 71 };  String firstString = new String(ascii);  System.out.println(firstString);  String secondString = new String(ascii, 1, 2);  System.out.println(secondString);  } }>

Wyjście
GFG FG>

Przykład 2:

Jawa
// Construct one string from another class GFG {  public static void main(String args[])  {  char characters[] = { 'G', 'f', 'g' };  String firstString = new String(characters);  String secondString = new String(firstString);  System.out.println(firstString);  System.out.println(secondString);  } }>

Wyjście
Gfg Gfg>

Często Zadawane Pytania

1. Czym są ciągi znaków w Javie?

Ciągi to typy obiektów, w których można przechowywać znaki jako elementy.

2. Dlaczego obiekty łańcuchowe są niezmienne w Javie?

Ponieważ Java używa koncepcji literału łańcuchowego. Załóżmy, że istnieje 5 zmiennych referencyjnych, wszystkie odnoszą się do jednego obiektu Sachin. Jeżeli jedna zmienna referencyjna zmieni wartość obiektu, będą miały na nią wpływ wszystkie zmienne referencyjne. Dlatego obiekty łańcuchowe są w Javie niezmienne.

3. Dlaczego Java używa koncepcji literału łańcuchowego?

Aby zwiększyć wydajność pamięci Java (ponieważ nie są tworzone żadne nowe obiekty, jeśli istnieją już w puli stałych łańcuchów).