JavaRush /وبلاگ جاوا /Random-FA /مقدمه ای بر String، StringBuffer و StringBuilder در جاوا

مقدمه ای بر String، StringBuffer و StringBuilder در جاوا

در گروه منتشر شد
سه کلاس در جاوا برای کار با داده های متنی وجود دارد: String ، StringBuffer و StringBuilder . هر توسعه دهنده ای در همان ابتدای یادگیری زبان با اولین آن مواجه می شود. در مورد دو باقی مانده چطور؟ تفاوت آنها چیست و چه زمانی بهتر است از یک کلاس استفاده کنیم؟ به طور کلی ، تفاوت بین آنها کم است ، اما بهتر است همه چیز را در عمل درک کنید :) مقدمه ای بر String، StringBuffer و StringBuilder در جاوا - 1

کلاس رشته

این کلاس دنباله ای از کاراکترها را نشان می دهد. تمام حرف های رشته تعریف شده در برنامه ها، مانند "This is String" نمونه هایی از کلاس String هستند. رشته دو ویژگی اساسی دارد:
  • این یک کلاس تغییر ناپذیر است
  • این کلاس آخر است
به طور کلی، کلاس String نمی تواند دارای فرزند ( final) باشد و نمونه های کلاس را نمی توان پس از ایجاد ( immutable) تغییر داد. این به کلاس String چندین مزیت مهم می دهد:
  1. به دلیل تغییر ناپذیری، کد هش یک نمونه از کلاس String ذخیره می شود. نیازی به ارزیابی هر بار نیست زیرا مقادیر فیلد شیء پس از ایجاد آن هرگز تغییر نخواهد کرد. این کارایی بالایی را هنگام استفاده از این کلاس به عنوان کلید برای HashMap.

  2. کلاس String را می توان در یک محیط چند رشته ای بدون همگام سازی اضافی استفاده کرد.

  3. یکی دیگر از ویژگی های کلاس String این است که +عملگر " " را در جاوا بارگذاری می کند. بنابراین، الحاق (افزودن) رشته ها بسیار ساده است:

public static void main(String[] args) {
    String command = "Follow" + " " + "the" + " " + "white" + " " + "rabbit";
    System.out.println(command); // Follow the white rabbit
}
در زیر هود، الحاق رشته ها توسط کلاس StringBuilder یا StringBuffer (به صلاحدید کامپایلر) و یک متد انجام می شود append(در مورد این کلاس ها کمی بعد صحبت خواهیم کرد). اگر نمونه‌هایی از کلاس String را با نمونه‌هایی از کلاس‌های دیگر اضافه کنیم، مورد دوم به یک نمایش رشته کاهش می‌یابد:
public static void main(String[] args) {
    Boolean b = Boolean.TRUE;
    String result = "b is " + b;
    System.out.println(result); //b is true
}
این یکی دیگر از ویژگی های جالب کلاس String است: اشیاء هر کلاس را می توان با استفاده از روش toString()تعریف شده در کلاس Objectو به ارث برده شدن توسط سایر کلاس ها به نمایش رشته ای فرستاد. اغلب متد toString() روی یک شی به صورت ضمنی فراخوانی می شود. به عنوان مثال، وقتی چیزی را روی صفحه نمایش می دهیم یا یک String را به یک شی از کلاس دیگر اضافه می کنیم. کلاس String یک ویژگی دیگر نیز دارد. تمام کلمات رشته ای تعریف شده در کد جاوا، مانند "asdf" در زمان کامپایل در حافظه پنهان ذخیره می شوند و به اصطلاح به استخر رشته اضافه می شوند. اگر کد زیر را اجرا کنیم:
String a = "Wake up, Neo";
String b = "Wake up, Neo";

System.out.println(a == b);
ما درست را در کنسول خواهیم دید زیرا متغیرها aدر واقع bبه همان نمونه ای از کلاس String اشاره می کنند که در زمان کامپایل به استخر رشته اضافه شده است. یعنی نمونه های مختلف کلاس با مقدار یکسان ایجاد نمی شود و حافظه ذخیره می شود.

ایرادات:

حدس زدن اینکه کلاس String در درجه اول برای کار با رشته ها مورد نیاز است دشوار نیست. اما در برخی موارد، ویژگی های فوق کلاس String می تواند از مزایا به معایب تبدیل شود. هنگامی که رشته ها در کد جاوا ایجاد می شوند، اغلب عملیات های زیادی روی آنها انجام می شود:
  • تبدیل رشته ها به ثبات های مختلف.
  • استخراج زیر رشته;
  • الحاق
  • و غیره.
بیایید به این کد نگاه کنیم:
public static void main(String[] args) {

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

    System.out.println("\"" + s + "\"");
}
در نگاه اول، به نظر می رسد که ما فقط خط "بیدار شو، نئو!" را ترجمه کردیم. به حروف بزرگ، فاصله های اضافی را از این رشته حذف کرده و آن را در گیومه قرار دهید. در واقع، به دلیل تغییرناپذیری کلاس String، در نتیجه هر عملیات، نمونه‌های رشته جدیدی ایجاد می‌شود و نمونه‌های قدیمی دور ریخته می‌شوند و حجم زیادی زباله تولید می‌کنند. چگونه از هدر رفتن حافظه جلوگیری کنیم؟

کلاس StringBuffer

برای مدیریت ایجاد زباله های موقت به دلیل تغییرات در یک شی String، می توانید از کلاس StringBuffer استفاده کنید. این mutableیک کلاس است، یعنی تغییر پذیر. یک شی از کلاس StringBuffer می تواند شامل مجموعه خاصی از کاراکترها باشد که طول و مقدار آنها را می توان با فراخوانی متدهای خاصی تغییر داد. بیایید ببینیم این کلاس چگونه کار می کند. برای ایجاد یک شی جدید، از یکی از سازنده های آن استفاده کنید، به عنوان مثال:
  • StringBuffer() - یک شی خالی (بدون کاراکتر) ایجاد می کند
  • StringBuffer (String str) - یک شی بر اساس متغیر str (شامل تمام کاراکترهای str در یک دنباله) ایجاد می کند.
تمرین:
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer("Not empty");
الحاق رشته ها از طریق StringBuffer در جاوا با استفاده از append. به طور کلی، متد appendدر کلاس StringBuffer به گونه ای بارگذاری می شود که تقریباً هر نوع داده ای را می پذیرد:
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];
}
متد شیئی را appendکه بر روی آن فراخوانی شده است (مانند بسیاری از متدهای دیگر) برمی گرداند که امکان فراخوانی آن را در یک "زنجیره" فراهم می کند. مثال بالا را می توان اینگونه نوشت:
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 چندین روش برای کار با رشته ها دارد. بیایید موارد اصلی را فهرست کنیم:
  • delete(int start, int end)- یک زیر رشته از کاراکترها را که از موقعیت شروع می شوند startو به پایان می رسند حذف می کندend
  • deleteCharAt(int index)- کاراکتر در موقعیت را حذف می کندindex
  • insert(int offset, String str)- یک خط را strدر موقعیت درج می کند offset. این روش insertنیز بیش از حد بارگذاری شده است و می‌تواند آرگومان‌های مختلفی بگیرد
  • replace(int start, int end, String str)- همه کاراکترها را از موقعیتی startبه موقعیت endدیگر جایگزین می کندstr
  • reverse()- ترتیب همه کاراکترها را معکوس می کند
  • substring(int start)- یک رشته فرعی را که از موقعیت شروع می شود برمی گرداند start
  • substring(int start, int end)start- یک رشته فرعی را که از موقعیتی به موقعیت دیگر شروع می شود، برمی گرداندend
لیست کاملی از متدها و سازنده ها در مستندات رسمی موجود است . روش های فوق چگونه کار می کنند؟ بیایید در عمل ببینیم:
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
    }

مزایای:

  1. همانطور که قبلا ذکر شد، StringBuffer یک کلاس قابل تغییر است، بنابراین کار با آن به اندازه String باعث ایجاد زباله در حافظه نمی شود. بنابراین، اگر تغییرات زیادی در رشته ها انجام شود، بهتر است از StringBuffer.

  2. StringBuffer یک کلاس امن برای رشته است. روش های آن همگام هستند و نمونه ها می توانند توسط چندین رشته به طور همزمان استفاده شوند.

ایرادات:

ایمنی نخ از یک طرف مزیت کلاس و از طرف دیگر یک نقطه ضعف است. روش های همزمان کندتر از روش های غیر همگام هستند. اینجاست که StringBuilder وارد عمل می شود. بیایید بفهمیم که چه نوع کلاس جاوا است - StringBuilder، چه روش هایی دارد و چه ویژگی هایی دارد.

کلاس StringBuilder

StringBuilder در جاوا کلاسی است که دنباله ای از کاراکترها را نشان می دهد. از هر نظر بسیار شبیه به StringBuffer است به جز ایمنی نخ. StringBuilder یک API شبیه به StringBuffer ارائه می دهد. بیایید این را با استفاده از یک مثال آشنا نشان دهیم، که جایگزین اعلان متغیرها از StringBufer به StringBuilder می شود:
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
}
تنها تفاوت این است که StringBuffer ایمن است و تمام روش های آن همگام هستند، در حالی که StringBuilder اینطور نیست. این تنها ویژگی است. StringBuilder در جاوا سریعتر از StringBuffer به دلیل عدم همگام سازی متدها است. بنابراین، در اکثر موارد، به جز در یک محیط چند رشته ای، بهتر است از StringBuilder برای یک برنامه جاوا استفاده کنید. ما همه چیز را در یک جدول مقایسه ای از سه کلاس خلاصه می کنیم:

String در مقابل StringBuffer در مقابل StringBuilder

رشته StringBuffer StringBuilder
تغییر پذیری Immutable(نه) mutable(آره) mutable(آره)
توسعه پذیری final(نه) final(نه) final(نه)
ایمنی نخ بله به دلیل تغییر ناپذیری بله به دلیل هماهنگی خیر
چه موقع باید استفاده کرد هنگام کار با رشته هایی که به ندرت اصلاح می شوند هنگام کار با رشته هایی که اغلب در یک محیط چند رشته ای اصلاح می شوند هنگام کار با رشته هایی که اغلب در یک محیط تک رشته ای اصلاح می شوند
می توانید این مبحث را با جزئیات بیشتر در سطح دوم کوئست Java Multithreading در دوره JavaRush مطالعه کنید:
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION