JavaRush /Java Blogu /Random-AZ /Java-da String, StringBuffer və StringBuilder-ə giriş

Java-da String, StringBuffer və StringBuilder-ə giriş

Qrupda dərc edilmişdir
Java-da mətn məlumatları ilə işləmək üçün üç sinif var: String , StringBufferStringBuilder . Hər bir tərtibatçı dili öyrənməyə başlayanda birincisi ilə qarşılaşır. Bəs qalan ikisi? Onların fərqləri nələrdir və bu və ya digər sinifdən nə vaxt istifadə etmək daha yaxşıdır? Ümumiyyətlə, aralarındakı fərq kiçikdir, amma praktikada hər şeyi başa düşmək daha yaxşıdır :) Java-da String, StringBuffer və StringBuilder-ə giriş - 1

String sinfi

Bu sinif simvollar ardıcıllığını təmsil edir. Proqramlarda müəyyən edilmiş bütün sətir literalları, məsələn, "This is String" String sinifinin nümunələridir. String iki əsas xüsusiyyətə malikdir:
  • bu dəyişməz sinifdir
  • bu son sinifdir
Ümumiyyətlə, String sinifinin uşaqları ola bilməz ( final) və yaradıldıqdan sonra sinfin nümunələri dəyişdirilə bilməz ( immutable). Bu String sinfinə bir sıra mühüm üstünlüklər verir:
  1. Dəyişməzliyə görə String sinfinin misalının hashkodu keşlənir. Onun hər dəfə qiymətləndirilməsinə ehtiyac yoxdur, çünki obyekt yaradıldıqdan sonra onun sahə dəyərləri heç vaxt dəyişməyəcək. Bu, bu sinfi üçün açar kimi istifadə edərkən yüksək performans verir HashMap.

  2. String sinfi əlavə sinxronizasiya olmadan çox yivli mühitdə istifadə edilə bilər.

  3. +String sinfinin başqa bir xüsusiyyəti Java-da " " operatorunu həddən artıq yükləməsidir . Beləliklə, sətirlərin birləşdirilməsi (əlavə edilməsi) olduqca sadədir:

public static void main(String[] args) {
    String command = "Follow" + " " + "the" + " " + "white" + " " + "rabbit";
    System.out.println(command); // Follow the white rabbit
}
Başlıq altında sətir birləşməsini StringBuilder və ya StringBuffer sinfi (tərtibçinin mülahizəsinə görə) və metod append(bir az sonra bu siniflər haqqında danışacağıq) həyata keçirir. String sinifinin nümunələrini digər siniflərin nümunələri ilə əlavə etsək, sonuncu simli təsvirə endiriləcək:
public static void main(String[] args) {
    Boolean b = Boolean.TRUE;
    String result = "b is " + b;
    System.out.println(result); //b is true
}
Bu, String sinifinin başqa bir maraqlı xüsusiyyətidir: istənilən sinfin obyektləri toString()sinifdə müəyyən edilmiş Objectvə bütün digər siniflər tərəfindən miras alınan metoddan istifadə edərək sətir təsvirinə çevrilə bilər. Çox vaxt obyektdə toString() metodu gizli çağırılır. Məsələn, biz ekranda nəyisə göstərdikdə və ya başqa sinif obyektinə String əlavə etdikdə. String sinfinin daha bir xüsusiyyəti var. "asdf" kimi Java kodunda müəyyən edilmiş bütün sətir literalları kompilyasiya zamanı keşlənir və sözdə sətir hovuzuna əlavə edilir. Aşağıdakı kodu işlədirsək:
String a = "Wake up, Neo";
String b = "Wake up, Neo";

System.out.println(a == b);
Biz konsolda doğru görəcəyik , çünki dəyişənlər ahəqiqətən btərtib zamanı sətir hovuzuna əlavə edilmiş String sinifinin eyni nümunəsinə istinad edəcəklər. Yəni, eyni qiymətə malik sinifin müxtəlif nümunələri yaradılmır və yaddaş saxlanılır.

Qüsurlar:

String sinfinin ilk növbədə sətirlərlə işləmək üçün lazım olduğunu təxmin etmək çətin deyil. Lakin bəzi hallarda String sinifinin yuxarıdakı xüsusiyyətləri üstünlüklərdən mənfi cəhətlərə çevrilə bilər. Java kodunda sətirlər yaradıldıqdan sonra onlar üzərində çoxlu əməliyyatlar yerinə yetirilir:
  • sətirlərin müxtəlif registrlərə çevrilməsi;
  • alt sətir çıxarılması;
  • birləşmə;
  • və s.
Bu koda baxaq:
public static void main(String[] args) {

    String s = " Wake up, Neo! ";
    s = s.toUpperCase();
    s = s.trim();

    System.out.println("\"" + s + "\"");
}
İlk baxışdan “Oyan, Neo!” sətirini indicə tərcümə etdiyimiz görünür. böyük hərflərə, bu sətirdən əlavə boşluqları çıxarın və onu dırnaqlara bükün. Əslində, String sinifinin dəyişməzliyinə görə, hər bir əməliyyat nəticəsində yeni sətir nümunələri yaradılır və köhnələri atılır, böyük miqdarda zibil əmələ gətirir. Yaddaş itkisinin qarşısını necə almaq olar?

StringBuffer sinfi

String obyektinə edilən dəyişikliklər səbəbindən müvəqqəti tullantıların yaradılmasını idarə etmək üçün StringBuffer sinfindən istifadə edə bilərsiniz. Bu mutablebir sinifdir, yəni. dəyişkən. StringBuffer sinfinin obyekti müəyyən simvollar toplusunu ehtiva edə bilər, onların uzunluğu və dəyəri müəyyən metodları çağırmaqla dəyişdirilə bilər. Gəlin görək bu sinif necə işləyir. Yeni bir obyekt yaratmaq üçün onun konstruktorlarından birini istifadə edin, məsələn:
  • StringBuffer() - boş (simvol olmayan) obyekt yaradacaq
  • StringBuffer(String str) - str dəyişəninə əsaslanan obyekt yaradacaq (eyni ardıcıllıqla str-nin bütün simvollarını ehtiva edir)
Təcrübə:
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer("Not empty");
Java-da StringBuffer vasitəsilə sətir birləşməsi append. Ümumiyyətlə, appendStringBuffer sinifindəki metod demək olar ki, istənilən məlumat növünü qəbul edə biləcək şəkildə həddən artıq yüklənir:
public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();

    sb.append(new Integer(2));
    sb.append("; ");
    sb.append(false);
    sb.append("; ");
    sb.append(Arrays.asList(1,2,3));
    sb.append("; ");

    System.out.println(sb); // 2; false; [1, 2, 3];
}
Metod, appendçağırıldığı obyekti qaytarır (bir çox digər üsullar kimi), bu da onu "zəncirdə" çağırmağa imkan verir. Yuxarıdakı nümunəni belə yazmaq olar:
public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();

    sb.append(new Integer(2))
            .append("; ")
            .append(false)
            .append("; ")
            .append(Arrays.asList(1,2,3))
            .append("; ");

    System.out.println(sb); // 2; false; [1, 2, 3];
}
StringBuffer sinfi sətirlərlə işləmək üçün bir sıra üsullara malikdir. Əsas olanları sadalayaq:
  • delete(int start, int end)— mövqedən başlayan start, bitən simvolların alt sətirini silirend
  • deleteCharAt(int index)— mövqedəki simvolu silirindex
  • insert(int offset, String str)str— mövqeyinə xətt daxil edir offset. Metod inserthəm də həddən artıq yüklənib və müxtəlif arqumentlər qəbul edə bilər
  • replace(int start, int end, String str)- mövqedən startmövqeyə bütün simvolları əvəz edəcəkendstr
  • reverse()— bütün simvolların sırasını tərsinə çevirir
  • substring(int start)- mövqedən başlayan alt sətir qaytaracaq start
  • substring(int start, int end)start- mövqedən mövqeyə başlayan alt sətir qaytaracaqend
Metodların və konstruktorların tam siyahısı rəsmi sənədlərdədir . Yuxarıda göstərilən üsullar necə işləyir? Gəlin praktikada baxaq:
public static void main(String[] args) {
     String numbers = "0123456789";

     StringBuffer sb = new StringBuffer(numbers);

     System.out.println(sb.substring(3)); // 3456789
     System.out.println(sb.substring(4, 8)); // 4567
     System.out.println(sb.replace(3, 5, "ABCDE")); // 012ABCDE56789

     sb = new StringBuffer(numbers);
     System.out.println(sb.reverse()); // 9876543210
     sb.reverse(); // Return the original order

     sb = new StringBuffer(numbers);
     System.out.println(sb.delete(5, 9)); // 012349
     System.out.println(sb.deleteCharAt(1)); // 02349
     System.out.println(sb.insert(1, "One")); // 0One2349
    }

Üstünlüklər:

  1. Artıq qeyd edildiyi kimi, StringBuffer dəyişən sinifdir, ona görə də onunla işləmək String ilə eyni miqdarda yaddaş zibilini yaratmır. Buna görə də, sətirlərə çoxlu dəyişikliklər edilirsə, istifadə etmək daha yaxşıdır StringBuffer.

  2. StringBuffer iplə təhlükəsiz sinifdir. Onun metodları sinxronlaşdırılır və nümunələr eyni vaxtda birdən çox başlıq tərəfindən istifadə edilə bilər.

Qüsurlar:

Bir tərəfdən iplik təhlükəsizliyi sinfin üstünlüyü, digər tərəfdən isə dezavantajdır. Sinxronlaşdırılmış üsullar sinxronlaşdırılmamış metodlardan daha yavaşdır. Burada StringBuilder işə düşür. Gəlin onun hansı Java sinfi olduğunu anlayaq - StringBuilder, onun hansı üsulları var və hansı xüsusiyyətləri var.

StringBuilder sinfi

Java-da StringBuilder simvollar ardıcıllığını təmsil edən bir sinifdir. O, ip təhlükəsizliyi istisna olmaqla, hər cəhətdən StringBuffer-ə çox bənzəyir. StringBuilder, StringBuffer-ə bənzər bir API təmin edir. Dəyişənlərin elanını StringBufer-dən StringBuilder-ə əvəz edərək, tanış bir nümunədən istifadə edərək bunu nümayiş etdirək:
public static void main(String[] args) {
    String numbers = "0123456789";

    StringBuilder sb = new StringBuilder(numbers);

    System.out.println(sb.substring(3)); //3456789
    System.out.println(sb.substring(4, 8)); //4567
    System.out.println(sb.replace(3, 5, "ABCDE")); //012ABCDE56789

    sb = new StringBuilder(numbers);
    System.out.println(sb.reverse()); //9876543210
    sb.reverse(); // Return the original order

    sb = new StringBuilder(numbers);
    System.out.println(sb.delete(5, 9)); //012349
    System.out.println(sb.deleteCharAt(1)); //02349
    System.out.println(sb.insert(1, "One")); //0One2349
}
Yeganə fərq ondan ibarətdir ki, StringBuffer iplik təhlükəsizdir və onun bütün metodları sinxronlaşdırılır, StringBuilder isə deyil. Bu yeganə xüsusiyyətdir. Metodların sinxronizasiya olunmaması səbəbindən Java-da StringBuilder StringBuffer-dən daha sürətlidir. Buna görə də, çox yivli mühit istisna olmaqla, əksər hallarda Java proqramı üçün StringBuilder-dən istifadə etmək daha yaxşıdır. Hər şeyi üç sinfin müqayisəli cədvəlində ümumiləşdiririk:

String vs StringBuffer vs StringBuilder

Simli StringBuffer StringBuilder
Dəyişkənlik Immutable(Yox) mutable(Bəli) mutable(Bəli)
Genişlənmə qabiliyyəti final(Yox) final(Yox) final(Yox)
İp təhlükəsizliyi Bəli, dəyişməzliyə görə Bəli, sinxronizasiyaya görə Yox
Nə vaxt istifadə etmək Nadir hallarda dəyişdiriləcək sətirlərlə işləyərkən Çox yivli mühitdə tez-tez dəyişdiriləcək sətirlərlə işləyərkən Tək yivli mühitdə tez-tez dəyişdiriləcək sətirlərlə işləyərkən
Bu mövzunu JavaRush kursunda Java Multithreading axtarışının ikinci səviyyəsində daha ətraflı öyrənə bilərsiniz:
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION