مقدمة
تقدم هذه المقالة بشكل أساسي المحتوى ذي الصلة حول تحليل رمز مصدر JDK و stringBuilder و StringBuffer. يتم مشاركته للرجوع إليه وتعلمك. لن أقول الكثير أدناه. دعونا نلقي نظرة على المقدمة التفصيلية معًا.
بيان فئة السلسلة
سلسلة الفئة النهائية العامة تنفذ java.io.serializable ، قابلة للمقارنة <string> ، charsequence {...}يستخدم فئة السلسلة معدلًا نهائيًا للإشارة إلى أنه لا يمكن موروثة. في الوقت نفسه ، يقوم أيضًا بتنفيذ ثلاث واجهات ، وتنفيذ الواجهة القابلة للتسلسل للإشارة إلى أنه يمكن تسلسل فئة السلسلة ؛ يوفر تطبيق واجهة <T> المماثلة بشكل أساسي طريقة مقارنة لمقارنة سلاسل السلسلة ؛ يقوم أيضًا بتنفيذ واجهة charsequence ، والتي تمثل أن Char يستحق تسلسلًا قابلًا للقراءة (Charbuffer ، الجزء ، السلسلة ، StringBuffer ، و StringBuilder ينفذ واجهة charsequence)
سلسلة الحقول الرئيسية وأوصاف السمة
/*قيمة صفيف الأحرف ، وتخزين الأحرف الفعلية في السلسلة*/القيمة النهائية الخاصة بـ char [] ؛/*قيمة التجزئة لقيمة السلسلة الافتراضية 0*/private int ؛ /*قيمة التجزئة لقيمة السلسلة الافتراضية 0*//*مقارن ، يستخدم لفرز كائنات السلسلة ، تستخدم طريقة المقارنة*/المقارنة النهائية الثابتة العامة <String> case_insensitive_order = new CaseensIncomParator () ؛
تحليل الطريقة الجزئية السلسلة
توفر فئة السلسلة سلسلة من المنشئين ، ولم يعد يوصى بالعديد منهم ، كما هو موضح في الشكل أدناه:
مُنشئ
فيما يلي تطبيقات مُنشئين شائعة الاستخدام:
// string str = new string ("123") public string (String Original) {this.value = Original.value ؛ this.hash = Original.hash ؛} // string str3 = new string (new char [] {'1' ، '2' ، '3'}) ؛ السلسلة العامة (قيمة char []) {// نسخ قيمة صفيف الأحرف لقيمة this.value = tharays.copyof (value ، value.length) ؛ }منطقية متساوية (كائن anobject)
تخطى فئة السلسلة طريقة متساوية لمقارنة هذه السلسلة مع الكائن المحدد. النتيجة صحيحة إذا وفقط إذا لم تكن المعلمة فارغة وهي كائن سلسلة يمثل نفس تسلسل الحرف مثل هذا الكائن.
منطقية عامة تساوي (كائن anobject) {// قارن مراجع الكائن مباشرة ، وإرجاع صحيح إذا (this == anobject) {return true ؛ } // قارن تسلسل حرف الكائن الحالي مع قيمة anobject if (anobject extleof string) {string anothertring = (string) anobject ؛ int n = value.length ؛ if (n == anotherstring.value.length) {char v1 [] = value ؛ char v2 [] = Anotherstring.value ؛ int i = 0 ؛ بينما (n--! = 0) {if (v1 [i]! = v2 [i]) return false ؛ i ++ ؛ } إعادة صواب ؛ }} إرجاع خطأ ؛ }int compareto (سلسلة anotherstring)
قارن تسلسل الأحرف من سلسلتين قليلا قليلا. إذا لم تكن الحرف قليلاً هي نفسها ، فأرجع الفرق في قيمة Unicode للحرفتين من هذا الشيء. جميع البتات هي نفسها ، وحساب الفرق في طول السلاسل. إذا كانت السلاسل هي نفسها ، فالتراجع 0.
public int compareto (String Anotherstring) {int len1 = value.length ؛ int len2 = anotherstring.value.length ؛ // خذ طول سلسلة بطول أصغر int lim = math.min (len1 ، len2) ؛ char v1 [] = value ؛ char v2 [] = Anotherstring.value ؛ int k = 0 ؛ بينما (k <lim) {// قارن قيمة تسلسل الأحرف للسلاسل اثنين واحدة تلو الأخرى. إذا لم يكن ذلك متساويًا ، فأرجع الفرق بين Unicode للحرفتين في هذا الموضع Char C1 = V1 [K] ؛ char c2 = v2 [k] ؛ if (c1! = c2) {return c1 - c2 ؛ // إرجاع الفرق بين Unicode} k ++ ؛ } // تتم مقارنة جميع أجزاء السلسلة الأصغر ، ويتم إرجاع الفرق بين أطوال السلاسل // إذا كانت السلاسل هي نفسها ، فإن الفرق بين الأطوال هو 0 ، أي نفس السلسلة تُرجع 0 len1 - len2 ؛ } يتم تنفيذ طريقة المقارنة (String Str) بشكل مشابه. يتم تجاهل الحالة العلوية والسفلية للأحرف أثناء المقارنة ، وطريقة التنفيذ هي كما يلي:
public int 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) ؛ char c2 = s2.charat (i) ؛ if (c1! = c2) {c1 = character.toupperCase (c1) ؛ C2 = الحرف. touppercase (C2) ؛ if (c1! = c2) {c1 = character.toLowerCase (c1) ؛ c2 = الحرف. tolowercase (c2) ؛ if (c1! = c2) {// no verflow بسبب الترويج الرقمي return c1 - c2 ؛ }}}} return n1 - n2 ؛ }سلسلة متدربة في السلسلة الأصلية ()
عندما يتم استدعاء طريقة المتدرب ، إذا كان المجمع يحتوي بالفعل على سلسلة مساوية لكائن السلسلة هذا (المحدد باستخدام طريقة (الكائن) المتساوي) ، يتم إرجاع السلسلة الموجودة في التجمع. خلاف ذلك ، أضف كائن السلسلة هذا إلى التجمع وإرجاع مرجع إلى كائن السلسلة هذا.
يتم تشغيل جميع الأوتار الحرفية وتخصيص التعبيرات الثابتة باستخدام طريقة المتدرب ، على سبيل المثال: String Str1 = "123" ؛
موقع ذاكرة السلسلة: تجمع أو كومة ثابتة
يمكن إنشاء كائنات السلسلة مباشرة من خلال الحرفيين أو من خلال المُنشئين. ما الفرق؟
1. يتم تخزين كائنات السلسلة التي تم إنشاؤها بواسطة السلاسل الحرفية أو الحرفية من خلال الربط "+" في البركة الثابتة. في حالة وجود تجمع ثابت أثناء الإنشاء الفعلي ، سيتم إرجاع المرجع مباشرة. إذا لم يكن موجودًا ، فسيتم إنشاء كائن السلسلة.
2. قم بإنشاء كائن سلسلة باستخدام المُنشئ ، وإنشاء كائن سلسلة مباشرة في الكومة
3. اتصل بالطريقة المتدربة ، وإرجاع الكائن سيتم وضعه في التجمع الثابت (إذا لم يكن موجودًا ، فسيتم وضعه في البركة الثابتة ، وإذا كان موجودًا ، فسيتم إرجاعه إلى المرجع)
فيما يلي مثال على تخصيص الذاكرة لكائنات السلسلة:
String str1 = سلسلة جديدة ("123") ؛ String str2 = "123" ؛ String str3 = "123" ؛ String str4 = str1.intern () ؛ system.out.println (str1 == str2) ؛ . // True STR2 ينشئ كائنًا في التجمع الثابت ، يقوم Str3 بإرجاع مرجع مباشرة إلى الكائن الذي تم إنشاؤه بواسطة STR2 ، لذلك يشير STR2 و Str3 إلى نفس الكائن في نظام البلياردو الثابت. // إرجاع STR4 True كائن بقيمة "123" في التجمع الثابت ، لذا فإن Str4 و Str2 و Str3 متساوون.حول مثال خياطة السلسلة:
الفئة العامة stringtest {public static Final String x = "ABC" ؛ // ثابت X @Test public void test () {String str5 = new string ("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==str7) ؛ // false system.out.println (str8 == Str7) ؛ // true system.out.println (str10 == Str7) ؛ // false system.out.println (x == Str9) ؛ //حقيقي} }سيكون الرمز المقلوب واضحًا في لمحة:
تخصيص الذاكرة كما يلي:
سلسلة ، StringBuffer ، StringBuilder
نظرًا لأن قيمة الممتلكات [] صفيف الأحرف لتخزين الأوتار التي يتم الحفاظ عليها داخليًا حسب نوع السلسلة ، يتم تعديل مع النهائي:
/** يتم استخدام القيمة لتخزين الأحرف. */قيمة char النهائية الخاصة [] ؛
إنه يشير إلى أنه يمكن تعديله بعد المهمة. لذلك ، نعتقد أن كائن السلسلة غير قابل للتغيير بمجرد إنشاؤه. إذا واجهت عمليات سلسلة الربط المتكررة أثناء التطوير ، إذا كنت تستخدم جهة الاتصال المقدمة بواسطة String أو تستخدم سلسلة الربط "+" مباشرة ، فسيتم إنشاء سلاسل جديدة بشكل متكرر ، والتي ستكون غير فعالة. يوفر Java فئتين أخريين: StringBuffer و StringBuilder ، والتي تستخدم لحل هذه المشكلة:
ألقِ نظرة على الكود التالي:
String str1 = "123" ؛ String str2 = "456" ؛ String str3 = "789" ؛ String str4 = "123" + "456" + "789" ؛ // إضافة الثوابت ، يتعرف المترجم تلقائيًا على String str4 = "123456789" String STR5 = Str1 + Str2 + Str3 ؛ // الربط المتغير سلسلة Stand ، يوصى باستخدام StringBuilder StringBuilder SB = جديد StringBuilder () ؛ SB.Append (STR1) ؛ SB.Append (Str2) ؛ SB.Append (STR3) ؛
فيما يلي تنفيذ فئة StringBuilder ، والتي تعترض فقط بعض التعليمات البرمجية التي تم تحليلها:
يمتد فئة Final Class public stringBuilder AbstractStringBuilder الأدوات java.io.serializable ، charsevenence {// split string Override public stringBuilder Aspend (String str) {// استدعاء الفئة الأصل AbstractStringBuilder.Append super.append (str) ؛ إرجاع هذا ؛ }} الخلاصة Class AbstractStringBuilder تنفذ التذييل ، charsevenence { / *** صفيف الأحرف الذي يخزن السلاسل ، نوع غير نهائي ، يختلف عن فئة السلسلة* / char [] القيمة ؛ /*** العد هو عدد الأحرف المستخدمة. */ int العد ؛ Public AbstractStringBuilder Append (String str) {if (str == null) return appendnull () ؛ int len = str.length () ؛ // تحقق مما إذا كان هناك حاجة إلى توسيع السعة إلى insureCapacityInternal (count + len) ؛ // انسخ String str to value str.getchars (0 ، len ، value ، count) ؛ العد += لين ؛ إرجاع هذا ؛} private void unsureCapacityInternal (int minimumcapacity) {// overflow -congious code // minimumcapacity = count+str.length // إذا كانت السعة بعد أن يتم تقسيم STR هي قيمة توسيع القيمة المتوسطة ، قم بإرجاع القيمة المتمثلة في توسيعها ، إرجاع القيمة الجديدة ؛ Arrays.copyof (القيمة ، NewCapacity (الحد الأدنى)) ؛ }} // stringbuilder التوسع الخاص int newCapacity (int mincapacity) {// رمز فائض ووعي // حساب قدرة التوسع // يتم توسيع طول صفيف التوسع الافتراضي بمقدار 2 أضعاف طول المجموعة الأصلي (القيمة []) ثم يضاف 2 إلى القاعدة. لماذا تضيف 2؟ int newCapacity = (value.length << 1) + 2 ؛ if (newCapacity - minicapacity <0) {newCapacity = minCapacity ؛ } العودة (newCapacity <= 0 || max_array_size - newCapacity <0)؟ HugeCapacity (Mincapacity): NewCapacity ؛ }}وينطبق الشيء نفسه على StringBuffer و StringBuilder. صفيف القيمة [] المحفوظة داخليًا قابلة للتغيير. الفرق الوحيد هو أن StringBuffer آمن مؤشر الترابط. يزامن جميع الطرق. StringBuilder هو مؤشر ترابط لا آمن. لذلك ، عندما يتم تشغيل متغيرات السلسلة متعددة الخيوط ومتغيرات السلسلة ، يفضل StringBuffer لمعالجة الربط السلسلة. خلاف ذلك ، يمكن استخدام StringBuilder. بعد كل شيء ، سيؤدي مزامنة الخيط أيضًا إلى تحقيق استهلاك معين.
لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون لمحتوى هذه المقالة قيمة مرجعية معينة لدراسة أو عمل الجميع. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل. شكرا لك على دعمك إلى wulin.com.