String, StringBuffer และ StringBuilder


คำตอบ:


378

ความแตกต่างที่ไม่แน่นอน:

Stringจะไม่เปลี่ยนรูปถ้าคุณพยายามที่จะเปลี่ยนค่าของพวกเขาวัตถุอื่นได้รับการสร้างในขณะที่StringBufferและStringBuilderจะไม่แน่นอนเพื่อให้พวกเขาสามารถเปลี่ยนค่าของพวกเขา

ความแตกต่างของหัวข้อความปลอดภัย:

ความแตกต่างระหว่างStringBufferและStringBuilderคือStringBufferความปลอดภัยของเธรด StringBuilderดังนั้นเมื่อความต้องการใช้ที่จะทำงานเฉพาะในหัวข้อเดียวแล้วมันจะดีกว่าที่จะใช้ จะมีประสิทธิภาพมากกว่าStringBuilderStringBuffer

สถานการณ์:

  • หากสตริงของคุณจะไม่เปลี่ยนให้ใช้คลาส String เพราะStringวัตถุไม่เปลี่ยนรูป
  • หากสตริงของคุณสามารถเปลี่ยนแปลงได้ (ตัวอย่างเช่น: จำนวนตรรกะและการดำเนินการในการสร้างสตริง) และจะสามารถเข้าถึงได้จากเธรดเดียวเท่านั้นโดยใช้ a StringBuilderดีพอ
  • หากสตริงของคุณสามารถเปลี่ยนแปลงได้และจะเข้าถึงได้จากหลายเธรดให้ใช้ a StringBufferเนื่องจากStringBufferเป็นซิงโครนัสเพื่อให้คุณมีความปลอดภัยของเธรด

16
นอกจากนี้การใช้ String สำหรับการดำเนินการทางตรรกะค่อนข้างช้าและไม่แนะนำเลยเนื่องจาก JVM แปลงสตริงเป็น StringBuffer ในไบต์ โอเวอร์เฮดจำนวนมากสูญเสียการแปลงจาก String เป็น StringBuffer และจากนั้นกลับสู่ String อีกครั้ง
Pieter van Niekerk

2
ดังนั้นStringsเมื่อเราปรับเปลี่ยนค่าวัตถุอื่นจะถูกสร้างขึ้น การอ้างอิงวัตถุเก่าเป็นโมฆะเพื่อที่อาจเป็นขยะที่รวบรวมโดยGCหรือเป็นขยะแม้แต่การเก็บรวบรวม?
Harsh Vardhan

@PietervanNiekerk คุณหมายความว่าอย่างไรกับการดำเนินการทางตรรกะ?
emlai

การดำเนินการเชิงตรรกะที่ฉันหมายถึงเป็นสตริงพื้นฐานตอนนี้สิ่งหนึ่งที่ฉันอยากจะถามตามที่ระบุไว้โดย @Peter เราควรเริ่มใช้ StringBuffer แทน String ในทุกกรณีหรือมีบางกรณีที่เฉพาะเจาะจงหรือไม่
JavaDragon

@bakkal ฉันสามารถใช้วิธีการทั้งหมดStringด้วยStringBuilderหรือไม่
roottraveller

47
  • คุณใช้Stringเมื่อโครงสร้างที่ไม่เปลี่ยนรูปเหมาะสม การรับลำดับอักขระใหม่จาก a Stringอาจมีการปรับประสิทธิภาพที่ยอมรับไม่ได้ไม่ว่าในเวลา CPU หรือหน่วยความจำ (การได้รับ substrings นั้นมีประสิทธิภาพของ CPU เนื่องจากข้อมูลไม่ได้ถูกคัดลอก
  • คุณใช้StringBuilderเมื่อคุณต้องการสร้างลำดับอักขระที่ไม่แน่นอนโดยปกติแล้วจะเชื่อมต่ออักขระหลายตัวเข้าด้วยกัน
  • คุณใช้StringBufferในสถานการณ์เดียวกันกับที่คุณจะใช้StringBuilderแต่เมื่อการเปลี่ยนแปลงกับสตริงที่ต้องถูกซิงโครไนซ์ (เนื่องจากหลายเธรดกำลังอ่าน / แก้ไขดัชนีสตริงบัฟเฟอร์)

ดูตัวอย่างที่นี่


2
กระชับ แต่ไม่สมบูรณ์มันขาดเหตุผลพื้นฐานในการใช้ StringBuilder / Buffer และนั่นคือการลดหรือกำจัดการจัดสรรใหม่และคัดลอกอาเรย์ของพฤติกรรมการเรียงต่อกันของสตริงปกติ

1
"คุณใช้ String เมื่อคุณจัดการกับสตริงที่ไม่เปลี่ยนรูป" - ไม่สมเหตุสมผล อินสแตนซ์ของ String ไม่เปลี่ยนรูปดังนั้นความคิดเห็นควรอ่าน "ใช้สตริงเมื่อการใช้หน่วยความจำเนื่องจากการเปลี่ยนแปลงไม่ได้สำคัญ" คำตอบที่ได้รับการยอมรับนั้นครอบคลุมพื้นฐานค่อนข้างดี
fooMonster

28

พื้นฐาน:

Stringเป็นคลาสที่ไม่เปลี่ยนรูปมันไม่สามารถเปลี่ยนแปลงได้ StringBuilderเป็นคลาสที่ไม่แน่นอนที่สามารถผนวกเข้าด้วยอักขระแทนที่หรือลบออกและในที่สุดก็แปลงเป็น a String StringBufferรุ่นซิงโครไนซ์ดั้งเดิมของStringBuilder

คุณควรเลือกStringBuilderในทุกกรณีที่คุณมีเพียงเธรดเดียวที่เข้าถึงวัตถุของคุณ

รายละเอียด:

โปรดทราบด้วยว่าStringBuilder/Buffersไม่ใช่เวทมนตร์พวกเขาใช้ Array เป็นวัตถุสำรองและ Array นั้นจะต้องได้รับการจัดสรรอีกครั้งเมื่อมันเต็ม ตรวจสอบให้แน่ใจและสร้างStringBuilder/Bufferวัตถุของคุณมีขนาดใหญ่พอที่เดิมซึ่งไม่จำเป็นต้องปรับขนาดใหม่อย่างต่อเนื่องทุกครั้งที่.append()ถูกเรียก

การปรับขนาดใหม่อาจลดลงมาก โดยพื้นฐานแล้วมันจะปรับขนาดของอาเรย์สำรองเป็น 2 เท่าของขนาดปัจจุบันทุกครั้งที่ต้องการขยาย ซึ่งอาจส่งผลให้ RAM จำนวนมากได้รับการจัดสรรและไม่ใช้เมื่อStringBuilder/Bufferคลาสเริ่มมีขนาดใหญ่ขึ้น

ใน Java String x = "A" + "B";ใช้StringBuilderฉากหลัง ดังนั้นในกรณีที่เรียบง่ายไม่มีประโยชน์ที่จะประกาศตัวคุณเอง แต่ถ้าคุณกำลังสร้างStringวัตถุที่มีขนาดใหญ่พูดน้อยกว่า 4k การประกาศStringBuilder sb = StringBuilder(4096);จะมีประสิทธิภาพมากกว่าการต่อข้อมูลหรือใช้ตัวสร้างเริ่มต้นซึ่งมีเพียง 16 ตัวอักษร หากคุณStringกำลังจะน้อยกว่า 10k ให้เริ่มต้นด้วย constructor ที่ 10k เพื่อความปลอดภัย แต่ถ้ามันเริ่มต้นที่ 10k คุณเขียนตัวละครมากกว่า 10k 1 ตัวมันจะได้รับการจัดสรรและคัดลอกไปยังอาร์เรย์ 20k ดังนั้นการเริ่มต้นสูงจึงดีกว่าต่ำ

ในกรณีที่ปรับขนาดอัตโนมัติที่อักขระที่ 17 อาร์เรย์สำรองได้รับการจัดสรรใหม่และคัดลอกไปที่ 32 ตัวอักษรเมื่ออักขระที่ 33 เกิดขึ้นอีกครั้งและคุณจะได้รับการจัดสรรใหม่และคัดลอก Array เป็น 64 ตัวอักษร คุณสามารถดูว่าสิ่งนี้ทำให้การจัดสรรและการคัดลอกซ้ำซ้อนเป็นจำนวนมากซึ่งเป็นสิ่งที่คุณพยายามหลีกเลี่ยงการใช้StringBuilder/Bufferในตอนแรก

นี่คือจากซอร์สโค้ด JDK 6 สำหรับ AbstractStringBuilder

   void expandCapacity(int minimumCapacity) {
    int newCapacity = (value.length + 1) * 2;
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
        newCapacity = minimumCapacity;
    }
        value = Arrays.copyOf(value, newCapacity);
    }

วิธีปฏิบัติที่ดีที่สุดคือการเริ่มต้นStringBuilder/Bufferให้ใหญ่กว่าที่คุณคิดเล็กน้อยถ้าคุณไม่รู้ว่าจะใหญ่แค่ไหนStringแต่คุณสามารถเดาได้ การจัดสรรหน่วยความจำมากกว่าหนึ่งเล็กน้อยที่คุณต้องการจะดีกว่าการจัดสรรและการคัดลอกจำนวนมาก

นอกจากนี้ระวังการกำหนดค่าเริ่มต้น a StringBuilder/Bufferด้วยStringซึ่งจะจัดสรรขนาดของอักขระ String + 16 เท่านั้นซึ่งโดยส่วนใหญ่แล้วจะเริ่มต้นการจัดสรรซ้ำอีกครั้งและรอบการคัดลอกที่คุณพยายามหลีกเลี่ยง ต่อไปนี้เป็นข้อมูลโดยตรงจากซอร์สโค้ด Java 6

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
    }

หากคุณบังเอิญจบลงด้วยอินสแตนซ์StringBuilder/Bufferที่คุณไม่ได้สร้างและไม่สามารถควบคุมนวกรรมิกที่เรียกว่ามีวิธีหลีกเลี่ยงพฤติกรรมการจัดสรรซ้ำและการคัดลอกที่แย่ลง โทร.ensureCapacity()ด้วยขนาดที่คุณต้องการเพื่อให้แน่ใจว่าผลลัพธ์ของคุณStringจะพอดี

ทางเลือก:

เช่นเดียวกับโน้ตถ้าคุณกำลังทำจริงๆหนัก Stringอาคารและการจัดการมีประสิทธิภาพมากขึ้นที่มุ่งเน้นทางเลือกที่เรียกว่าเชือก

อีกทางเลือกหนึ่งคือการสร้างการStringListดำเนินการโดยการจัดกลุ่มย่อยArrayList<String>และเพิ่มตัวนับเพื่อติดตามจำนวนอักขระใน.append()การดำเนินการกลายพันธุ์ทุกรายการและอื่น ๆ จากนั้นจึงแทนที่.toString()เพื่อสร้างStringBuilderขนาดที่แน่นอนที่คุณต้องการและวนผ่านรายการและสร้าง ผลลัพธ์คุณยังสามารถสร้างStringBuilderตัวแปรอินสแตนซ์และ 'แคช' ผลลัพธ์.toString()และต้องสร้างใหม่เมื่อมีการเปลี่ยนแปลงบางอย่างเท่านั้น

นอกจากนี้อย่าลืมว่าString.format()เมื่อสร้างผลลัพธ์ที่มีการจัดรูปแบบคงที่ซึ่งสามารถปรับให้เหมาะสมโดยคอมไพเลอร์เมื่อมันทำให้ดีขึ้น


1
ไม่String x = "A" + "B";จริงๆที่จะรวบรวม StringBuilder หรือไม่? ทำไมมันไม่คอมไพล์String x = "AB";มันควรใช้ StringBuilder เท่านั้นถ้าส่วนประกอบไม่รู้จักในเวลาคอมไพล์
Matt Greer

มันอาจปรับค่าคงที่สตริงออกฉันไม่สามารถเรียกคืนจากครั้งล่าสุดที่ถอดรหัสรหัสไบต์ แต่ฉันรู้ว่าถ้ามีตัวแปรใด ๆ ในนั้นจะใช้การใช้งาน StringBuilder แน่นอน คุณสามารถดาวน์โหลดซอร์สโค้ด JDK และค้นหาด้วยตัวคุณเอง "A" + "B" เป็นตัวอย่างที่วางแผนไว้อย่างแน่นอน

ฉันสงสัยเกี่ยวกับ String.format () ฉันไม่เคยเห็นมาก่อนว่ามันถูกใช้ในโครงการ โดยปกติจะเป็น StringBuilder ปกติแล้วมันมักจะเป็น "A" + "B" + "C" เพราะคนขี้เกียจ;) ฉันมักจะใช้ StringBuilder เสมอแม้ว่ามันจะมีเพียงสองสายที่ถูกต่อกันเพราะในอนาคตอาจจะมีการต่อสายเพิ่มเติม . ฉันไม่เคยใช้ String.format () เป็นหลักเพราะฉันไม่เคยจำสิ่งที่ JDK นำมาใช้ - ฉันเห็นว่าเป็น JDK1.5 ฉันจะใช้มันเพื่อสนับสนุนตัวเลือกอื่น ๆ
jamiebarrow

9

คุณหมายถึงการต่อเรียงหรือไม่?

ตัวอย่างโลกจริง: คุณต้องการที่จะสร้างออกสตริงใหม่อื่น ๆ อีกมากมาย

ตัวอย่างเช่นการส่งข้อความ:

เชือก

String s = "Dear " + user.name + "<br>" + 
" I saw your profile and got interested in you.<br>" +
" I'm  " + user.age + "yrs. old too"

StringBuilder

String s = new StringBuilder().append.("Dear ").append( user.name ).append( "<br>" ) 
          .append(" I saw your profile and got interested in you.<br>") 
          .append(" I'm  " ).append( user.age ).append( "yrs. old too")
          .toString()

หรือ

String s = new StringBuilder(100).appe..... etc. ...
// The difference is a size of 100 will be allocated upfront as  fuzzy lollipop points out.

StringBuffer (ไวยากรณ์ตรงกับ StringBuilder ผลที่แตกต่าง)

เกี่ยวกับ

StringBuffer เมื่อเทียบกับ StringBuilder

อดีตถูกซิงโครไนซ์และในภายหลังไม่ใช่

ดังนั้นหากคุณเรียกใช้หลายครั้งในเธรดเดียว (ซึ่งเป็น 90% ของเคส) StringBuilderจะทำงานเร็วขึ้นมากเพราะจะไม่หยุดเพื่อดูว่ามันเป็นเจ้าของล็อคเธรดหรือไม่

ดังนั้นจึงแนะนำให้ใช้StringBuilder(เว้นแต่แน่นอนว่าคุณมีมากกว่าหนึ่งเธรดที่เข้าถึงมันในเวลาเดียวกันซึ่งหายาก)

Stringการต่อข้อมูล ( ใช้ตัวดำเนินการ + ) อาจได้รับการปรับให้เหมาะสมโดยคอมไพเลอร์ที่จะใช้StringBuilderภายใต้ดังนั้นจึงไม่ใช่สิ่งที่ต้องกังวลอีกต่อไปในวันก่อนหน้าของ Java นี่เป็นสิ่งที่ทุกคนพูดว่าควรหลีกเลี่ยงค่าใช้จ่าย สร้างวัตถุ String ใหม่ คอมไพเลอร์สมัยใหม่จะไม่ทำเช่นนี้อีกต่อไป แต่ก็เป็นวิธีปฏิบัติที่ดีที่จะใช้StringBuilderแทนในกรณีที่คุณใช้คอมไพเลอร์ "เก่า"

แก้ไข

สำหรับผู้ที่อยากรู้อยากเห็นนี่คือสิ่งที่คอมไพเลอร์ทำสำหรับชั้นนี้:

class StringConcatenation {
    int x;
    String literal = "Value is" + x;
    String builder = new StringBuilder().append("Value is").append(x).toString();
}

javap -c StringConcatenation

Compiled from "StringConcatenation.java"
class StringConcatenation extends java.lang.Object{
int x;

java.lang.String literal;

java.lang.String builder;

StringConcatenation();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   new #2; //class java/lang/StringBuilder
   8:   dup
   9:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   12:  ldc #4; //String Value is
   14:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   17:  aload_0
   18:  getfield    #6; //Field x:I
   21:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   24:  invokevirtual   #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   27:  putfield    #9; //Field literal:Ljava/lang/String;
   30:  aload_0
   31:  new #2; //class java/lang/StringBuilder
   34:  dup
   35:  invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   38:  ldc #4; //String Value is
   40:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   43:  aload_0
   44:  getfield    #6; //Field x:I
   47:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   50:  invokevirtual   #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   53:  putfield    #10; //Field builder:Ljava/lang/String;
   56:  return

}

บรรทัดที่มีหมายเลข 5 - 27 สำหรับสตริงชื่อ "literal"

บรรทัดที่มีหมายเลข 31-53 สำหรับสตริงชื่อ "builder"

ไม่มีความแตกต่างรหัสเดียวกันนี้ถูกเรียกใช้สำหรับทั้งสองสตริง


2
นี่เป็นตัวอย่างที่ไม่ดีจริงๆ การเริ่มต้น StringBuilder ด้วย "Dear" หมายถึง. append () แรกจะทำให้เกิดการจัดสรรและคัดลอก ลบล้างประสิทธิภาพใด ๆ ที่คุณกำลังพยายามที่จะได้รับจากการต่อข้อมูล "ปกติ" โดยสมบูรณ์ ตัวอย่างที่ดีกว่าคือการสร้างด้วยขนาดเริ่มต้นที่จะเก็บเนื้อหาทั้งหมดของสตริงสุดท้าย

1
โดยทั่วไปแล้วไม่ใช่วิธีที่ดีที่จะใช้การStringBuilderทำ String concatenation ทางด้านขวามือของการมอบหมาย การนำไปใช้ที่ดีจะใช้ StringBuilder อยู่เบื้องหลัง นอกจากนี้ตัวอย่างของคุณ"a" + "b"จะได้รับการเรียบเรียงเขียนเป็นตัวอักษรเดียว"ab"แต่ถ้าคุณใช้มันจะส่งผลในสองสายความจำเป็นที่จะStringBuilder append()
Mark Peters

@ มาร์คฉันไม่ได้ตั้งใจจะใช้"a"+"b"แต่จะพูดว่าString concatenationเกี่ยวกับอะไรที่ฉันเปลี่ยนให้ชัดเจน สิ่งที่คุณไม่พูดคือทำไมการฝึกฝนที่ดีจึงไม่ใช่วิธีที่ดี นั่นคือสิ่งที่คอมไพเลอร์ (สมัยใหม่) ทำ @ ฟัซซี่ฉันเห็นด้วยโดยเฉพาะอย่างยิ่งเมื่อคุณรู้ว่าขนาดของสตริงสุดท้ายจะเป็นอย่างไร (aprox)
OscarRyz

1
ฉันไม่คิดว่ามันเป็นการปฏิบัติที่ไม่ดีโดยเฉพาะแต่ฉันไม่ต้องการคำแนะนำใด ๆ โดยทั่วไป มัน clunky และยากที่จะอ่านและ verbose มากเกินไป นอกจากนี้ยังส่งเสริมให้เกิดข้อผิดพลาดเช่นคุณที่คุณกำลังแยกตัวอักษรสองตัวที่ไม่สามารถรวบรวมเป็นหนึ่ง เฉพาะในกรณีที่โปรไฟล์บอกฉันว่ามันสร้างความแตกต่างฉันจะทำในแบบของคุณ
Mark Peters

@ Mark เข้าใจแล้ว ฉันคิดใน"รหัสก้อนใหญ่ ๆ เช่นเทมเพลต"และไม่ได้อยู่ในสตริงตัวอักษรปกติทุกตัว แต่ใช่ฉันเห็นด้วยเนื่องจากพวกเขาทำสิ่งเดียวกันทุกวันนี้มันไม่สมเหตุสมผล (10 ปีที่แล้วเป็นเหตุผลที่ปฏิเสธการเปลี่ยนแปลงในการแก้ไขโค้ด) :)
OscarRyz

8
-------------------------------------------------- --------------------------------
                  String StringBuffer StringBuilder
-------------------------------------------------- --------------------------------                 
พื้นที่จัดเก็บ ฮีปพูลของสตริงคงที่
แก้ไขได้ ไม่ (ไม่เปลี่ยนรูป) ใช่ (ไม่แน่นอน) ใช่ (ไม่แน่นอน)
กระทู้ปลอดภัย ใช่ใช่ไม่
 ประสิทธิภาพ | เร็วมากเร็วมาก
-------------------------------------------------- --------------------------------

ทำไมประสิทธิภาพของสตริงจึงเร็วและประสิทธิภาพของ StringBuffer ช้ามาก?
gaurav

1
@gaurav คุณสามารถอ่านรหัสแหล่งที่มาของวิธีการทั้งหมดใน StringBuffer เป็นsynchronisedและที่ว่าทำไม
ได้ยิน

8

ตระกูลสตริง

เชือก

String classหมายถึงสตริงตัวอักษร สตริงตัวอักษรทั้งหมดในโปรแกรม Java เช่น"abc"ถูกใช้เป็นอินสแตนซ์ของคลาสนี้

วัตถุสตริงจะไม่เปลี่ยนรูปเมื่อมีการสร้างเราไม่สามารถเปลี่ยนแปลงได้ ( สตริงมีค่าคงที่ )

  • ถ้า String จะถูกสร้างขึ้นโดยใช้คอนสตรัคหรือวิธีการแล้วสตริงเหล่านั้นจะถูกเก็บไว้ในกองหน่วยความจำSringConstantPoolเช่นเดียวกับ แต่ก่อนที่จะบันทึกในพูลจะเรียกใช้intern()วิธีตรวจสอบความพร้อมใช้งานของวัตถุที่มีเนื้อหาเดียวกันในพูลโดยใช้วิธีเท่ากับ ถ้า String-copy พร้อมใช้งานในพูลจากนั้นส่งคืนการอ้างอิง มิฉะนั้นวัตถุสตริงจะถูกเพิ่มไปยังสระว่ายน้ำและส่งกลับการอ้างอิง

    • ภาษา Java ให้การสนับสนุนพิเศษสำหรับตัวดำเนินการต่อสตริง ( +) และสำหรับการแปลงวัตถุอื่นเป็นสตริง การต่อข้อมูลสตริงจะดำเนินการผ่านคลาส StringBuilder (หรือ StringBuffer) และวิธีการต่อท้าย

    String heapSCP = new String("Yash");
    heapSCP.concat(".");
    heapSCP = heapSCP + "M";
    heapSCP = heapSCP + 777;
    
    // For Example: String Source Code 
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
  • StringConstantPoolตัวอักษรของสตริงจะถูกเก็บไว้ใน

    String onlyPool = "Yash";

StringBuilderและStringBufferเป็นลำดับตัวอักษรที่ไม่แน่นอน นั่นหมายความว่าเราสามารถเปลี่ยนค่าของวัตถุเหล่านี้ได้ StringBuffer มีวิธีการเดียวกับ StringBuilder แต่แต่ละวิธีใน StringBuffer จะถูกซิงโครไนซ์ดังนั้นจึงเป็นเธรดที่ปลอดภัย

  • ข้อมูล StringBuffer และ StringBuilder สามารถสร้างได้โดยใช้ตัวดำเนินการใหม่เท่านั้น ดังนั้นพวกเขาจะถูกเก็บไว้ในหน่วยความจำฮีป

  • อินสแตนซ์ของ StringBuilder ไม่ปลอดภัยสำหรับการใช้หลายเธรด หากจำเป็นต้องมีการซิงโครไนซ์ดังกล่าวขอแนะนำให้ใช้ StringBuffer

    StringBuffer threadSafe = new StringBuffer("Yash");
    threadSafe.append(".M");
    threadSafe.toString();
    
    StringBuilder nonSync = new StringBuilder("Yash");
    nonSync.append(".M");
    nonSync.toString();
  • StringBuffer และ StringBuilder จะมีวิธีการพิเศษเช่น. และreplace(int start, int end, String str)reverse()

    หมายเหตุ : StringBuffer และ SringBuilder Appendable Interfaceมีความไม่แน่นอนที่พวกเขาให้การดำเนินงานของ


เมื่อใดควรใช้อันไหน

  • String Classถ้าคุณจะไม่ได้ไปเปลี่ยนค่าทุกครั้งที่แล้วดีกว่าที่จะใช้ ในฐานะที่เป็นส่วนหนึ่งของ Generics ถ้าคุณต้องการที่จะเรียงลำดับหรือเปรียบเทียบค่าไปแล้วสำหรับComparable<T>String Class

    //ClassCastException: java.lang.StringBuffer cannot be cast to java.lang.Comparable
    Set<StringBuffer> set = new TreeSet<StringBuffer>();
    set.add( threadSafe );
    System.out.println("Set : "+ set);
  • หากคุณกำลังจะปรับเปลี่ยนค่าทุกครั้งที่ไปสำหรับ StringBuilder ซึ่งเร็วกว่า StringBuffer ถ้ามีหลายเธรดกำลังแก้ไขค่า go สำหรับ StringBuffer


4

นอกจากนี้ยังStringBufferปลอดภัยต่อเธรดซึ่งStringBuilderไม่ใช่

ดังนั้นในสถานการณ์แบบเรียลไทม์เมื่อเธรดที่แตกต่างเข้าถึงอยู่StringBuilderอาจมีผลลัพธ์ที่ไม่ได้กำหนดไว้


3

โปรดทราบว่าหากคุณกำลังใช้ Java 5 หรือใหม่กว่าคุณควรใช้แทนStringBuilder StringBufferจากเอกสาร API:

ในฐานะของการปล่อย JDK 5 StringBuilderชั้นนี้ได้รับการเสริมด้วยชั้นเทียบเท่าที่ออกแบบมาสำหรับการใช้งานโดยด้ายเดี่ยว StringBuilderชั้นโดยทั่วไปควรจะนำมาใช้ในการตั้งค่าให้เป็นหนึ่งในนี้มันสนับสนุนทั้งหมดของการดำเนินงานเดียวกัน แต่มันก็เป็นได้เร็วขึ้นเช่นจะดำเนินการประสานไม่มี

ในทางปฏิบัติคุณแทบจะไม่เคยใช้สิ่งนี้จากหลาย ๆ เธรดในเวลาเดียวกันดังนั้นการซิงโครไนซ์ที่StringBufferไม่จำเป็นต้องอยู่เหนือศีรษะเสมอไป


3

ส่วนตัวผมไม่คิดว่าจะมีการใช้งานใด ๆ StringBufferในโลกที่แท้จริงสำหรับ เมื่อใดที่ฉันจะต้องการสื่อสารระหว่างหลายเธรดด้วยการจัดการลำดับอักขระ? ไม่ได้มีประโยชน์อะไรเลย แต่ฉันอาจจะยังไม่เห็นแสง :)


3

ความแตกต่างระหว่าง String และอีกสองคลาสคือ String นั้นไม่เปลี่ยนรูปและอีกสองคลาสเป็นคลาสที่ไม่แน่นอน

แต่ทำไมเรามีสองคลาสเพื่อจุดประสงค์เดียวกัน

เหตุผลคือStringBufferด้ายปลอดภัยและStringBuilderไม่ StringBuilderเป็นคลาสใหม่บนStringBuffer Apiและถูกนำมาใช้JDK5และแนะนำเสมอถ้าคุณกำลังทำงานในสภาพแวดล้อมเธรดเดียวตามมากFaster

สำหรับรายละเอียดที่สมบูรณ์คุณสามารถอ่านhttp://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/


2

ใน java, Stringนั้นไม่เปลี่ยนรูป การไม่เปลี่ยนรูปเราหมายถึงว่าเมื่อมีการสร้างสตริงเราไม่สามารถเปลี่ยนค่าได้ StringBufferไม่แน่นอน เมื่อสร้างวัตถุ StringBuffer เราเพียงผนวกเนื้อหาเข้ากับค่าของวัตถุแทนการสร้างวัตถุใหม่ StringBuilderคล้ายกับ StringBuffer แต่ไม่ปลอดภัยสำหรับเธรด วิธีการของ StingBuilder ไม่ได้ถูกซิงโครไนซ์ แต่เมื่อเปรียบเทียบกับ Strings อื่น ๆ Stringbuilder จะทำงานเร็วที่สุด คุณสามารถเรียนรู้ความแตกต่างระหว่างString, StringBuilder และ StringBufferโดยการใช้พวกเขา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.