ฉันเชื่อว่าทุกคนมีความเข้าใจที่ดีถึงความแตกต่างระหว่าง String และ StringBuffer แต่คาดว่ายังมีสหายหลายคนที่ไม่ชัดเจนเกี่ยวกับหลักการทำงานของทั้งสองคลาส วันนี้ฉันจะทบทวนแนวคิดนี้สำหรับทุกคนและโดย วิธีที่ J2SE 5.0 นำคลาสการจัดการตัวละครใหม่ - StringBuilder (อย่ารีบโยนอิฐใส่ฉัน ฉันยังเงียบขรึม ฉันไม่ได้พูดถึง C# ที่นี่ Java ก็มีคลาส StringBuilder เช่นกัน) แล้วอะไรคือความแตกต่างระหว่าง StringBuilder และ StringBuffer และคลาส String ที่เราพบกันครั้งแรก? เราควรใช้อันไหนในสถานการณ์ที่แตกต่างกัน? ฉันอยากจะแบ่งปันความคิดเห็นของฉันเกี่ยวกับหมวดหมู่เหล่านี้ และฉันก็หวังว่าทุกคนจะสามารถแสดงความคิดเห็นได้ ทุกคนเคยทำผิดพลาด และในขณะที่แก้ไขให้ถูกต้อง มันก็เป็นโอกาสที่ดีที่จะเรียนรู้
กล่าวโดยย่อ ความแตกต่างด้านประสิทธิภาพหลักระหว่างประเภท String และประเภท StringBuffer ก็คือ แท้จริงแล้ว String เป็นอ็อบเจ็กต์ที่ไม่เปลี่ยนรูป (ทำไม? ถามนักออกแบบของ Java เหตุใด String จึงไม่ใช่ประเภทเนทิฟ) ดังนั้น ทุกครั้งที่มีการเปลี่ยนแปลงประเภท String ที่จริงแล้วจะเทียบเท่ากับการสร้างออบเจ็กต์ String ใหม่ จากนั้นชี้ตัวชี้ไปที่ออบเจ็กต์ String ใหม่ ดังนั้นจึงเป็นการดีที่สุดที่จะไม่ใช้ String สำหรับสตริงที่เปลี่ยนแปลงเนื้อหาบ่อยครั้ง เนื่องจากในแต่ละครั้งที่มีการสร้างออบเจ็กต์ จะมีผลกระทบต่อประสิทธิภาพของระบบ โดยเฉพาะเมื่อใช้หน่วยความจำ เมื่อมีวัตถุที่ไม่ได้อ้างอิงมากเกินไป GC ของ JVM จะเริ่มทำงานและความเร็วจะค่อนข้างช้าอย่างแน่นอน นี่คือตัวอย่างที่ไม่เหมาะสมอย่างยิ่ง:
สตริง S1 = "abc";
สำหรับ(int I = 0; I < 10,000; I ++) // สำหรับจำลองการเรียกใช้โปรแกรมหลายครั้ง
-
S1 + = "def";
S1 = "เอบีซี";
-
หากเป็นกรณีนี้หลังจาก for loop เสร็จสิ้น หากวัตถุในหน่วยความจำยังไม่ถูกล้างโดย GC ก็จะมีหน่วยความจำมากกว่า 20,000 รายการในหน่วยความจำเป็นตัวเลขที่น่าประหลาดใจและหากเป็นระบบที่หลาย ๆ คนใช้ คนแล้วจำนวนไม่มากดังนั้นทุกคนจึงต้องระมัดระวังในการใช้งาน
หากคุณใช้คลาส StringBuffer ผลลัพธ์จะแตกต่างออกไป แต่ละครั้งผลลัพธ์จะเป็นการดำเนินการบนออบเจ็กต์ StringBuffer เอง แทนที่จะสร้างออบเจ็กต์ใหม่แล้วเปลี่ยนการอ้างอิงออบเจ็กต์ โดยทั่วไปแล้ว เราขอแนะนำให้ใช้ StringBuffer โดยเฉพาะอย่างยิ่งเมื่อวัตถุสตริงมีการเปลี่ยนแปลงบ่อยครั้ง ในบางกรณีพิเศษ การต่อสตริงของอ็อบเจ็กต์ String จะถูกตีความโดย JVM ว่าเป็นการต่อกันของอ็อบเจ็กต์ StringBuffer ดังนั้นในกรณีเหล่านี้ ความเร็วของอ็อบเจ็กต์ String จะไม่ช้ากว่าอ็อบเจ็กต์ StringBuffer และโดยเฉพาะอ็อบเจ็กต์สตริงต่อไปนี้ สร้างขึ้นในหมู่พวกเขาประสิทธิภาพของสตริงนั้นเร็วกว่า StringBuffer มาก:
สตริง S1 = “นี่เป็นเพียง” + “ง่าย” + “ทดสอบ”;
StringBuffer Sb = new StringBuilder("นี่เป็นเพียง").append("simple").append("test");
คุณจะประหลาดใจที่พบว่าความเร็วในการสร้างออบเจ็กต์ String S1 นั้นเร็วเกินไป และในเวลานี้ StringBuffer ไม่มีข้อได้เปรียบในเรื่องความเร็วเลย อันที่จริงนี่เป็นเคล็ดลับของ JVM ในสายตาของ JVM
String S1 = “นี่เป็นเพียงการทดสอบ” + “แบบง่าย” + “การทดสอบ”; จริงๆ แล้ว มันคือ: String S1 = “นี่เป็นเพียงการทดสอบง่ายๆ เท่านั้น”; แต่สิ่งที่ทุกคนควรทราบที่นี่คือถ้าสตริงของคุณมาจากวัตถุ String อื่น ความเร็วจะไม่เร็วขนาดนั้น ตัวอย่างเช่น:
String S2 = “นี่เป็นเพียง”;
สตริง S3 = "ธรรมดา";
สตริง S4 = "ทดสอบ";
สตริง S1 = S2 +S3 + S4;
ในเวลานี้ JVM จะทำงานในลักษณะเดิม และความเร็วการสร้างของออบเจ็กต์ S1 จะไม่เร็วเหมือนเมื่อก่อน เราสามารถทำการทดสอบเพื่อตรวจสอบได้ในภายหลัง
จากนี้เราจะได้ข้อสรุปขั้นตอนแรก: ในกรณีส่วนใหญ่ StringBuffer > String
และ StringBuilder เปรียบเทียบกับพวกมันได้อย่างไร? ให้ฉันแนะนำสั้น ๆ ก่อน StringBuilder เป็นคลาสที่เพิ่มใหม่ใน JDK5.0 ความแตกต่างระหว่างมันกับ StringBuffer มีดังนี้ (ที่มา: JavaWorld):
Java.lang.StringBuffer ลำดับอักขระที่ไม่แน่นอนของเธรด บัฟเฟอร์สตริงคล้ายกับ String แต่ไม่สามารถแก้ไขได้ บัฟเฟอร์สตริงสามารถใช้ได้อย่างปลอดภัยโดยหลายเธรด วิธีการเหล่านี้สามารถซิงโครไนซ์ได้เมื่อจำเป็น เพื่อให้การดำเนินการทั้งหมดบนอินสแตนซ์ใด ๆ ปรากฏขึ้นตามลำดับอนุกรมที่สอดคล้องกับลำดับการเรียกเมธอดที่ทำโดยแต่ละเธรดที่เกี่ยวข้อง
บัฟเฟอร์สตริงแต่ละตัวมีความจุที่แน่นอน ตราบใดที่ความยาวของลำดับอักขระที่มีอยู่ในบัฟเฟอร์สตริงไม่เกินความจุนี้ ก็ไม่จำเป็นต้องจัดสรรอาร์เรย์บัฟเฟอร์ภายในใหม่ ความจุนี้จะเพิ่มขึ้นโดยอัตโนมัติหากบัฟเฟอร์ภายในล้น เริ่มต้นจาก JDK 5.0 คลาสที่เทียบเท่าสำหรับการใช้เธรดเดี่ยวได้ถูกเพิ่มให้กับคลาสนี้ ซึ่งก็คือ StringBuilder โดยทั่วไปควรใช้คลาส StringBuilder ในการกำหนดค่าตามความชอบสำหรับคลาสนี้ เนื่องจากคลาสนี้สนับสนุนการดำเนินการเดียวกันทั้งหมด แต่จะเร็วกว่าเนื่องจากไม่ได้ทำการซิงโครไนซ์
แต่ไม่ปลอดภัยที่จะใช้อินสแตนซ์ของ StringBuilder กับหลายเธรด หากจำเป็นต้องมีการซิงโครไนซ์ ขอแนะนำให้ใช้ StringBuffer
จากที่กล่าวไป ฉันคิดว่าทุกคนสามารถเข้าใจความแตกต่างระหว่างพวกเขาได้ ดังนั้นเรามาสร้างความแตกต่างโดยทั่วไปด้านล่าง:
ในกรณีส่วนใหญ่ StringBuilder > StringBuffer
ดังนั้น ตามทฤษฎีบทการถ่ายโอนของอสมการนี้: ในกรณีส่วนใหญ่ StringBuilder > StringBuffer > String (ยิ่งจำนวนการดำเนินการมากเท่าไรก็ยิ่งมีเสถียรภาพมากขึ้นเท่านั้น)
รับเวลาเริ่มต้นของระบบ = System.currentTimeMillis(); long end = System.currentTimeMillis();
สำหรับ(i=0;i<str.length()/2;i++)
ถ้า(str.charAt(i)!=str.charAt(str.length()-i-1))
หยุดพัก;
ถ้า(i>=str.length()/2)
JOptionPane.showMessageDialog(null,"เป็นสตริงพาลินโดรม");
อื่น
JOptionPane.showMessageDialog(null, "ไม่ใช่สตริงพาลินโดรม");
-
-
-
ถ้า(str.เท่ากับ(str2))
JOptionPane.showMessageDialog(null,"เป็นสตริงพาลินโดรม");
อื่น
JOptionPane.showMessageDialog(null, "ไม่ใช่สตริงพาลินโดรม");
-
-