คำนำ
บทความนี้ส่วนใหญ่แนะนำเนื้อหาที่เกี่ยวข้องเกี่ยวกับการวิเคราะห์ซอร์สโค้ด JDK, StringBuilder และ StringBuffer มันถูกแบ่งปันสำหรับการอ้างอิงและการเรียนรู้ของคุณ ฉันจะไม่พูดด้านล่างมากนัก มาดูการแนะนำรายละเอียดร่วมกันกันเถอะ
คำสั่งของคลาสสตริง
สตริงคลาสสุดท้ายของสาธารณะใช้ java.io.serializable, เทียบเท่า <string>, charsequence {…}คลาสสตริงใช้ตัวดัดแปลงสุดท้ายเพื่อระบุว่าไม่สามารถสืบทอดได้ ในเวลาเดียวกันมันยังใช้สามอินเตอร์เฟสโดยใช้อินเตอร์เฟส serializable เพื่อระบุว่าคลาสสตริงสามารถทำให้เป็นอนุกรม; การใช้อินเทอร์เฟซ <T> ที่เปรียบเทียบได้ส่วนใหญ่ให้วิธีการเปรียบเทียบสำหรับการเปรียบเทียบสตริงสตริง ยังใช้อินเทอร์เฟซ Charequence ซึ่งแสดงว่าถ่านนั้นมีค่าลำดับที่อ่านได้ (Charbuffer, เซ็กเมนต์, สตริง, StringBuffer และ StringBuilder ยังใช้อินเทอร์เฟซ Charsequence)
ฟิลด์สตริงหลักและคำอธิบายแอตทริบิวต์
/*ค่าอาร์เรย์อักขระ, การจัดเก็บอักขระจริงในสตริง*/ค่าถ่านสุดท้ายส่วนตัว [];/*ค่าแฮชของค่าเริ่มต้นสตริง 0*/int แฮชส่วนตัว; /*ค่าแฮชของค่าเริ่มต้นสตริง 0*//*ตัวเปรียบเทียบที่ใช้ในการเรียงลำดับวัตถุสตริงวิธีการเปรียบเทียบ ignorecase ใช้*/public Static Final Comparator <String> CASE_INSENSITITY_ORDER = ใหม่ CASEINSENSENSITIVECOMPARATOR ();
การวิเคราะห์วิธีการบางส่วนของสตริง
คลาสสตริงมีชุดของตัวสร้างและหลายคนไม่แนะนำอีกต่อไปดังแสดงในรูปด้านล่าง:
ตัวสร้าง
นี่คือการใช้งานของตัวสร้างที่ใช้กันทั่วไปสองตัว:
// string str = สตริงใหม่ ("123") สตริงสาธารณะ (สตริงต้นฉบับ) {this.value = original.value; this.hash = Original.hash;} // string str3 = สตริงใหม่ (char ใหม่ [] {'1', '2', '3'}); สตริงสาธารณะ (ค่าถ่าน []) {// คัดลอกค่าอาร์เรย์อักขระไปที่ค่า this.value = array.copyof (value.length); -บูลีนเท่ากับ (Object Anobject)
คลาสสตริงจะแทนที่วิธี Equals เพื่อเปรียบเทียบสตริงนี้กับวัตถุที่ระบุ ผลลัพธ์จะเป็นจริงถ้าพารามิเตอร์ไม่ได้เป็นโมฆะและเป็นวัตถุสตริงที่แสดงลำดับอักขระเดียวกันกับวัตถุนี้
บูลีนสาธารณะเท่ากับ (Object Anobject) {// เปรียบเทียบการอ้างอิงวัตถุโดยตรงและส่งคืนจริงถ้า (this == anobject) {return true; } // เปรียบเทียบลำดับอักขระของวัตถุปัจจุบันที่มีค่า anobject ถ้า (anobject anoBject string) {string anothertring = (string) anobject; int n = value.length; if (n == anothertring.value.length) {char v1 [] = value; ถ่าน v2 [] = anotherstring.value; int i = 0; ในขณะที่ (n--! = 0) {ถ้า (v1 [i]! = v2 [i]) ส่งคืนเท็จ; i ++; } return true; }} return false; -int compereto (String anotherstring)
เปรียบเทียบลำดับอักขระของสองสตริงทีละบิต หากอักขระบิตไม่เหมือนกันให้ส่งคืนความแตกต่างในค่า Unicode ของอักขระสองตัวของบิตนั้น บิตทั้งหมดเหมือนกันคำนวณความแตกต่างในความยาวของสองสาย หากทั้งสองสตริงเหมือนกันให้ส่งคืน 0
public int compereto (String anothertring) {int len1 = value.length; int len2 = anotherstring.value.length; // ใช้ความยาวของสตริงที่มีความยาวน้อยกว่า int lim = math.min (len1, len2); ถ่าน v1 [] = ค่า; ถ่าน v2 [] = anotherstring.value; int k = 0; ในขณะที่ (k <lim) {// เปรียบเทียบค่าลำดับอักขระของสองสตริงหนึ่งทีละหนึ่ง หากไม่เท่ากันให้ส่งคืนความแตกต่างระหว่าง Unicode ของอักขระทั้งสองที่ตำแหน่งนั้นถ่าน C1 = V1 [K]; ถ่าน C2 = v2 [k]; if (c1! = c2) {return c1 - c2; // ส่งคืนความแตกต่างระหว่าง Unicode} K ++; } // บิตทั้งหมดของสตริงที่เล็กกว่าจะถูกเปรียบเทียบและความแตกต่างระหว่างความยาวของสองสตริงจะถูกส่งคืน // ถ้าทั้งสองสตริงเหมือนกันความแตกต่างระหว่างความยาวคือ 0 นั่นคือสตริงเดียวกันส่งคืน 0 กลับ LEN1 - LEN2; - วิธีการเปรียบเทียบ ignorecase (string str) ถูกนำมาใช้ในทำนองเดียวกัน ตัวอักษรบนและล่างของอักขระจะถูกละเว้นในระหว่างการเปรียบเทียบและวิธีการใช้งานมีดังนี้:
INT Public Compare (String S1, String S2) {int N1 = S1.Length (); int n2 = s2.length (); int min = math.min (n1, n2); สำหรับ (int i = 0; i <min; i ++) {char c1 = s1.charat (i); ถ่าน C2 = S2.Charat (i); if (c1! = c2) {c1 = character.touppercase (c1); c2 = character.touppercase (C2); if (c1! = c2) {c1 = character.toLowercase (c1); c2 = character.toLowercase (C2); if (c1! = c2) {// ไม่มีการล้นเนื่องจากโปรโมชั่นตัวเลขส่งคืน c1 - c2; }}}} ส่งคืน n1 - n2; -Native String Intern ()
เมื่อมีการเรียกใช้วิธีการฝึกงานหากพูลมีสตริงเท่ากับวัตถุสตริงนี้แล้ว (พิจารณาด้วยเมธอดเท่ากับ (วัตถุ)) สตริงในพูลจะถูกส่งคืน มิฉะนั้นเพิ่มวัตถุสตริงนี้ลงในพูลและส่งคืนการอ้างอิงไปยังวัตถุสตริงนี้
สตริงที่แท้จริงและการแสดงออกคงที่การกำหนดสตริงทั้งหมดดำเนินการโดยใช้วิธีการฝึกงานเช่น: string str1 = "123";
ตำแหน่งหน่วยความจำสตริง: พูลคงที่หรือกอง
วัตถุสตริงสามารถสร้างได้โดยตรงผ่านตัวอักษรหรือผ่านตัวสร้าง ความแตกต่างคืออะไร?
1. วัตถุสตริงที่สร้างขึ้นโดยสตริงตัวอักษรหรือตัวอักษรผ่าน "+" การประกบจะถูกเก็บไว้ในสระคงที่ หากสระว่ายน้ำคงที่ในระหว่างการสร้างจริงการอ้างอิงจะถูกส่งคืนโดยตรง หากไม่มีอยู่วัตถุสตริงจะถูกสร้างขึ้น
2. สร้างวัตถุสตริงโดยใช้ตัวสร้างและสร้างวัตถุสตริงโดยตรงในฮีป
3. เรียกใช้วิธีการฝึกงานและส่งคืนวัตถุจะถูกใส่ลงในพูลคงที่ (หากไม่มีอยู่มันจะถูกวางลงในพูลคงที่และถ้ามันมีอยู่มันจะถูกส่งกลับไปยังการอ้างอิง)
ต่อไปนี้เป็นตัวอย่างของการจัดสรรหน่วยความจำของวัตถุสตริง:
string str1 = สตริงใหม่ ("123"); string str2 = "123"; string str3 = "123"; string str4 = str1.intern (); System.out.println (str1 == str2); // FALSE STR1 สร้างวัตถุในฮีป, STR2 สร้างวัตถุในระบบพูลคงที่. // True STR2 สร้างวัตถุในสระว่ายน้ำคงที่ STR3 จะส่งคืนการอ้างอิงไปยังวัตถุที่สร้างโดย STR2 โดยตรงดังนั้น STR2 และ STR3 ชี้ไปที่วัตถุเดียวกันในระบบพูลคงที่. // True STR4 ส่งคืนวัตถุด้วยค่าของ "123" ในสระคงที่ดังนั้น STR4, STR2 และ STR3 นั้นเท่ากันเกี่ยวกับตัวอย่างการเย็บสตริง:
คลาสสาธารณะ StringTest {สตริงสุดท้ายคงที่ x = "ABC"; // ค่าคงที่ x @test สาธารณะทดสอบโมฆะ () {string str5 = สตริงใหม่ ("abc"); string str6 = str5+"def"; // สร้าง string str7 = "abc"+"def"; // สตริงพูลคงที่ str8 = x+"def"; // x เป็นค่าคงที่และค่าได้รับการแก้ไขดังนั้นค่าของ x+"def" ได้ถูกตั้งค่าเป็น ABCDEF ในความเป็นจริงหลังจากการรวบรวมรหัสจะเทียบเท่ากับ string str8 = "abcdef" string str9 = "abc"; string str10 = str9+"def"; //system.out.println(str6==tr7); // false system.out.println (str8 == str7); // true system.out.println (str10 == str7); // false system.out.println (x == str9); //จริง} }รหัสที่ถอดรหัสจะชัดเจนได้อย่างรวดเร็ว:
การจัดสรรหน่วยความจำมีดังนี้:
String, StringBuffer, StringBuilder
เนื่องจากค่าคุณสมบัติ [] อาร์เรย์อักขระสำหรับการจัดเก็บสตริงที่เก็บรักษาไว้ภายในตามประเภทสตริงจะถูกแก้ไขด้วยขั้นสุดท้าย:
/** ค่าใช้สำหรับการจัดเก็บอักขระ */ค่าถ่านสุดท้ายส่วนตัว [];
มันบ่งชี้ว่าสามารถแก้ไขได้หลังจากการมอบหมาย ดังนั้นเราเชื่อว่าวัตถุสตริงไม่เปลี่ยนรูปเมื่อสร้างขึ้นเมื่อสร้างขึ้น หากคุณพบการทำงานของสตริงการประกบกันบ่อยครั้งในระหว่างการพัฒนาหากคุณใช้รายชื่อติดต่อโดยสตริงหรือใช้สตริง "+" การประกบโดยตรงสตริงใหม่จะถูกสร้างขึ้นบ่อยครั้งซึ่งจะไม่มีประสิทธิภาพ Java มีคลาสอื่นอีกสองคลาส: StringBuffer และ StringBuilder ซึ่งใช้ในการแก้ปัญหานี้:
ดูรหัสต่อไปนี้:
string str1 = "123"; string str2 = "456"; String str3 = "789"; String str4 = "123" + "456" + "789"; // เพิ่มค่าคงที่คอมไพเลอร์จะจดจำสตริง str4 = "123456789" สตริง str5 = str1 + str2 + str3; // ตัวแปรสตริง Sticket ขอแนะนำให้ใช้ StringBuilder StringBuilder SB = New StringBuilder (); SB.Append (STR1); SB.Append (STR2); SB.Append (STR3);
ต่อไปนี้คือการใช้งานคลาส StringBuilder ซึ่งจะสกัดกั้นบางส่วนของรหัสที่วิเคราะห์:
Public Final Class StringBuilder ขยาย AbstractStringBuilder ใช้ java.io.serializable, charsequence {// split string @Override public StringBuilder ผนวก (String str) {// เรียกคลาสหลัก คืนสิ่งนี้; - Abstract Class AbstractStringBuilder ใช้งานได้ต่อท้าย, charsequence { / *** อาร์เรย์อักขระที่เก็บสตริงประเภทที่ไม่ใช่รอบรองชนะเลิศซึ่งแตกต่างจากคลาสสตริง* / char [] ค่า; /*** จำนวนคือจำนวนอักขระที่ใช้ */ int count; Public AbstractStringBuilder ผนวก (String str) {ถ้า (str == null) return uptendNull (); int len = str.length (); // ตรวจสอบว่าต้องมีการขยายกำลังการผลิตเพื่อ ensurecapacityInternal (นับ + len); // คัดลอกสตริง str ไปยังค่า str.getchars (0, len, ค่า, นับ); นับ += len; ส่งคืนสิ่งนี้;} โมฆะส่วนตัว ensurecapacityInternal (int minimumcapacity) {// รหัสที่ใส่ใจเกินกำลัง // minimumcapacity = count+str.length // ถ้าความจุหลังจาก str เป็น spliced มากกว่าความจุของค่า array.copyof (ค่า, newCapacity (ขั้นต่ำสุด)); }} // StringBuilder Expansion ส่วนตัว int newCapacity (int mincapacity) {// รหัสที่มีสติเกิน // คำนวณความสามารถในการขยายความสามารถ // ความยาวการขยายตัวเริ่มต้นเริ่มต้น 2 เท่าของจำนวนเดิม (ค่า []) ความยาวกลุ่มและ 2 จะถูกเพิ่มลงในกฎ ทำไมต้องเพิ่ม 2? int newCapacity = (value.length << 1) + 2; if (newCapacity - mincapacity <0) {newCapacity = mincapacity; } return (newCapacity <= 0 || max_array_size - newcapacity <0)? Hugecapacity (mincapacity): newcapacity; -เช่นเดียวกับ StringBuffer และ StringBuilder ค่า [] อาร์เรย์อักขระที่เก็บรักษาไว้ภายในนั้นไม่แน่นอน ความแตกต่างเพียงอย่างเดียวคือ StringBuffer คือ Thread-Safe มันซิงโครไนซ์ทุกวิธี StringBuilder เป็นเธรด-ไม่ปลอดภัย ดังนั้นเมื่อการดำเนินการแบบมัลติเธรดและการแชร์ตัวแปรสตริง StringBuffer เป็นที่ต้องการสำหรับการประมวลผลการประกบสตริง มิฉะนั้นสามารถใช้ StringBuilder ได้ ท้ายที่สุดแล้วการซิงโครไนซ์เธรดจะนำมาซึ่งการบริโภคบางอย่าง
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะมีค่าอ้างอิงบางอย่างสำหรับการศึกษาหรือที่ทำงานของทุกคน หากคุณมีคำถามใด ๆ คุณสามารถฝากข้อความไว้เพื่อสื่อสาร ขอบคุณสำหรับการสนับสนุน Wulin.com