1. مقدمة في سلسلة ، تحليلات المصدر الأساليب الشائعة تحليل رمز المصدر
2. تحليل تجمع ثابت السلسلة
الطرق المشتركة
يساوي
تقليم
يستبدل
CONCAT
ينقسم
Startswith و endswith
فرعية
touppercase () و tolowercase ()
المقارنة
مقدمة إلى السلسلة
يتم تعديل فئة السلسلة بواسطة Final ، مما يعني أن كائن السلسلة هو غير قابل للتغيير ، ويفضل البرامج المتزامنة Immutables. تنفذ فئة السلسلة الواجهات القابلة للتسلسل ، قابلة للمقارنة ، و charequence.
ابدأ بقطعة رمز:
public void stringtest () {string a = "a"+"b" +1 ؛ السلسلة B = "AB1" ؛ system.out.println (a == b) ؛}خمن ما هي النتيجة؟ إذا كان استنتاجك صحيحًا. حسنًا ، دعونا نحصل على رمز آخر:
public void stringtest () {String a = new String ("AB1") ؛ السلسلة B = "AB1" ؛ system.out.println (a == b) ؛}ما هي النتيجة؟ الإجابة الصحيحة خاطئة.
دعونا نرى كيف تم تجميع الرمز بواسطة المترجم
// الكود الأول public void stringtest () {string a = "ab1" ؛ السلسلة B = "AB1" ؛ system.out.println (a == b) ؛} // الكود الثاني public void stringtest () {string a1 = new string ("AB1") ؛ السلسلة B = "AB1" ؛ system.out.println (a1 == b) ؛}بمعنى آخر ، تم تحسين الجزء الأول من الكود خلال فترة الترجمة لأن المترجم وجد أن تأثيرات "A"+"B" +1 و "AB1" متماثلة ، وكلاهما يتكون من المناطق المنفصلة. ولكن لماذا تتناول ذاكرتهم نفس الشيء؟ إذا كنت لا تزال مهتمًا بذلك ، فلنلقي نظرة على بعض رموز المصدر المهمة لفئة السلسلة.
رمز المصدر
1. سمات السلسلة
تحتوي فئة السلسلة على صفيف char غير قابل للتغيير لتخزين السلاسل ، ويتم استخدام التجزئة المتغيرة int لتخزين قيمة التجزئة المحسوبة.
/** يتم استخدام القيمة لتخزين الأحرف. */قيمة char النهائية الخاصة [] ؛/** ذاكرة التخزين المؤقت رمز التجزئة للسلسلة*/private int. // الافتراضي إلى 0/** استخدم SerialVersionuid من JDK 1.0.2 لعملية التشغيل البيني*/خاص ثابت نهائي طويل المسلسل = -6849794470754667710L ؛
2. مُنشئ السلسلة
// البنائين بدون معلمات غير مجدية عمومًا ، لأن القيمة هي سلسلة عامة غير قابلة للتغيير () {this.value = new char [0] ؛} // المعلمة هي سلسلة السلسلة العامة (السلسلة الأصلية) {this.value = Original.value ؛ this.hash = Original.hash ؛} // المعلمة عبارة عن صفيف char ، استخدم فئة المصفوفات في حزمة java.utils لنسخ السلسلة العامة (قيمة char [] بايت [] ، إزاحة int ، طول int ، سلسلة charsetname) يلقي UnduportedEncodingException {if (charsetName == null) رمي nullpointerxception جديد ("charsetname") ؛ checkbounds (البايت ، الإزاحة ، الطول) ؛ هذا.3. الطرق الشائعة للسلسلة
1. يساوي
Boolean يساوي (الكائن anobject) منطقية عامة يساوي (كائن anobject) {// إذا كان المرجع هو نفس الكائن ، وإرجاع صحيح إذا (هذا == anobject) {return true ؛ } // إذا لم تكن بيانات سلسلة النوع غير سلسلة ، فأرجعس خطأ إذا (anobject string of string) {string anotherstring = (string) anobject ؛ int n = value.length ؛ // إذا كان طول صفيف char غير متساوٍ ، فأعود خطأ إذا (n == anotherstring.value.length) {char v1 [] = value ؛ char v2 [] = Anotherstring.value ؛ int i = 0 ؛ . i ++ ؛ } // كل حرف متساوٍ ، إرجاع العودة الحقيقية ؛ }} إرجاع خطأ ؛}String e1 = "good" ؛ string e2 = "good alday" ؛ e1.equals (e2) ؛ // إرجاع خطأ
1 أولاً ، حدد ما إذا كان يتم الرجوع إلى نفس الكائن == ، أي ، حدد ما إذا كانت عناوين ذاكرة المرجعين هي نفسها. إذا كان الأمر نفسه ، فسيعود مباشرة إلى True.
ستحدد 2 ما إذا كانت الأنواع متشابهة وما إذا كانت نفس نوع البيانات
3 إذا تم استخدام نفس النوع ، فإن طول صفيف الأحرف المحول هو نفسه.
4 قارن ما إذا كان كل حرف هو نفسه من الخلف إلى الأمام
أمر الحكم =》 1. عنوان الذاكرة 2. نوع البيانات 3. طول صفيف الأحرف 4.
2. المقارنة
int compareto (string anotherstring) public int compareto (string anotherstring) {// طول سلسلة الكائن الخاص len1 int len1 = value.length ؛ // طول سلسلة الكائن المقارنة len2 = anotherstring.value.length ؛ // الحد الأدنى لقيمة طول سلسلتين lim int lim = math.min (len1 ، len2) ؛ char v1 [] = value ؛ char v2 [] = Anotherstring.value ؛ int k = 0 ؛ // من الحرف الأول من القيمة إلى الحد الأدنى للطول ، إذا كانت الأحرف غير متساوية ، فأعود نفسها (الأحرف التي لا تكون فيها الكائنات متساوية - الأحرف التي تتم مقارنتها) بينما (k <lim) {char c1 = v1 [k] ؛ char c2 = v2 [k] ؛ if (c1! = c2) {return c1 - c2 ؛ } k ++ ؛ } // إذا كانت الجبهات كلها متساوية ، فالتراجع (طولها - طول الكائن الذي يتم مقارنته) إرجاع len1 - len2 ؛}String CO1 = "Hello" ؛ String CO2 = "Hello" ؛ String CO3 = "Hello You" ؛ System.out.println (CO1.comPareto (CO2)) ؛ // 0system.out.println (co1.compareto (CO3)) ؛ // -4
هذه الطريقة مكتوبة ببراعة ، ويمكنك الحكم على حجم الشخصية من 0 أولاً.
إذا كانت المقارنة بين الكائنين يمكن أن تقارن الأحرف لا تزال متساوية ، فسيتم إرجاع طول الكائن الذي يتم مقارنته مباشرة. إذا كان طول السلاسل متساوية ، فإن العائد هو 0 ، الذي يحكم بذكاء المواقف الثلاثة.
3. HashCode
int hashcode () public int hashcode () {int h = hash ؛ // إذا لم يتم حساب التجزئة ولم تكن السلسلة فارغة ، فسيتم إجراء حساب hashcode إذا (h == 0 && value.length> 0) {char val [] = value ؛ // عملية الحساب // s [0]*31^(n-1) + s [1]*31^(n-2) + ... + s [n-1] for (int i = 0 ؛ i <value.length ؛ i ++) {h = 31*h + val [i] ؛ } // hash issignment hash = h ؛ } العودة H ؛}string a = "toyou" ؛ char val [] = a.tochararray () ؛ char c1 = 't' ؛ char c2 = 'a' ؛ int f = c1 ؛ int e = c2 ؛ system.out.println (e) ؛ // 97 Asystem.out.println (F) ؛ // 116 tsystem.out.println (31*val [0]) ؛ // 3596System.out.println (31*C1) ؛ // 3596 // حساب HashCode لأنه يمكن تحويل أحرف char تلقائيًا إلى تشكيل int المقابل
تتجاوز فئة السلسلة طريقة hashcode ، وطريقة hashcode في الكائن هي مكالمة أصلية.
يتم حساب تجزئة فئة السلسلة باستخدام متعدد الحدود. يمكننا الحصول على نفس التجزئة من خلال سلاسل مختلفة. لذلك ، فإن رمز التجزئة لكائنين سلسلة هو نفسه ، وهو ما لا يعني أن السلاسلان متماثلان.
يجب أن يكون رمز التجزئة لكائن السلسلة نفسه هو نفسه ، لكن رمز التجزئة هو نفسه ، وليس بالضرورة نفس الكائن
4.Startswith
boolean startswith (بادئة السلسلة ، int toffset) startswith public boolean (بادئة السلسلة ، int toffset) {char ta [] = value ؛ int to = toffset ؛ char pa [] = prefix.value ؛ int po = 0 ؛ int pc = prepix.value.length ؛ // ملاحظة: قد تكون Toffset بالقرب من -1 >>> 1. // إذا كان عنوان البدء أقل من 0 أو (عنوان بدء + طول الكائن المقارن) يكون أكبر من طول الكائن الخاص ، فأرجع خطأ إذا ((toffset <0) || (toffset> value.length - pc)) {return false ؛ } // قارن من نهاية الكائن الذي يتم مقارنته بينما (--pc> = 0) {if (ta [to ++]! = pa [po ++]) {return false ؛ }} return true ؛} startswith boolean public (بادئة السلسلة) {return startswith (prefix ، 0) ؛ String d = "www.58fxp.com" ؛ System.out.println (D.Startswith ("www")) ؛ // true system.out.println (d.endswith ("com")) ؛ // حقيقيالبدء وإنهاء المقارنة هي طرق شائعة. على سبيل المثال ، عند الحكم على ما إذا كانت السلسلة من بروتوكول HTTP ، أو في البداية الحكم على ما إذا كان الملف هو ملف MP3 ، يمكنك استخدام هذه الطريقة للمقارنة.
5.concat
سلسلة concat (string str) سلسلة public concat (string str) {int otherlen = str.length () ؛ // إذا كانت السلسلة المضافة فارغة ، فقم بإرجاع الكائن نفسه إذا (otherlen == 0) {return this ؛ } int len = value.length ؛ char buf [] = arrays.copyof (value ، len + otherlen) ؛ str.getchars (buf ، len) ؛ إرجاع سلسلة جديدة (buf ، true) ؛} String Cat = "must" ؛ String NewCat = cat.concat ("نعم") ؛ // كثيرا نعمطريقة التسلس هي أيضًا واحدة من الطرق الشائعة الاستخدام. يحدد أولاً ما إذا كانت السلسلة المضافة فارغة لتحديد ما إذا كان سيتم إنشاء كائن جديد.
1 إذا كان طول الحرف المقسم 0 ، فأعود مباشرة إلى كائن الحرف الأصلي
2 الأحرف المقسمة ليست فارغة وإرجاع كائن حرف جديد
تحديد طول الحرف لإنشاء كائن جديد
6. الاستراحة
سلسلة استبدال (char oldchar ، char newchar) سلسلة عامة استبدال (char oldchar ، char newchar) {// قارن القيم القديمة والجديدة أولاً إذا (oldchar! = newchar) {int len = value.length ؛ int i = -1 ؛ char [] val = value ؛ / * تجنب getfield opcode */ // ابحث عن الموضع الذي تظهر فيه القيمة القديمة أولاً بينما (++ i <len) {if (val [i] == oldchar) {break ؛ }} // من هذا الموضع ، حتى النهاية ، استبدل القيمة القديمة التي تظهر بالقيمة الجديدة إذا كانت (i <len) {char buf [] = new char [len] ؛ لـ (int j = 0 ؛ j <i ؛ j ++) {buf [j] = val [j] ؛ } بينما (i <len) {char c = val [i] ؛ buf [i] = (c == oldchar)؟ Newchar: C ؛ i ++ ؛ } إرجاع سلسلة جديدة (buf ، true) ؛ }} إرجاع هذا ؛} سلسلة R1 = "كيف تفعل" ؛ String R2 = r1.replace ("do" ، "IS") ؛ System.out.println (R2) ؛ // كيف حالكتحتوي هذه الطريقة أيضًا على بعض الذكاء ، مثل معرفة مكان ظهور القيمة القديمة في البداية ، مما يوفر بعض وقت المقارنة.
يتم الحكم على طريقة استبدال (String Oldstr ، String NewsTr) من خلال التعبيرات العادية.
7.Trim
String trim () public string trim () {int len = value.length ؛ int st = 0 ؛ char [] val = value ؛ / * تجنب getfield opcode */ // ابحث عن الموضع بدون مسافات أمام السلسلة بينما ((st <len) && (val [st] <= '')) {st ++ ؛ } // ابحث عن الموضع بدون مسافات في نهاية السلسلة بينما ((st <len) && (val [len-1] <= '')) {len-- ؛ } // إذا لم تكن هناك مسافات في المقدمة وبعدها ، أعد السلسلة نفسها ((ST> 0) || (len <value.length))؟ Substring (ST ، Len): هذا ؛} سلسلة T1 = "public void" ؛ // مساحة واحدة في المقدمة وبعد system.out.println ("T1:"+t1.length ()) ؛ // 13 مع سلسلة طول الفضاء T2 = t1.trim () ؛ System.out.println ("T2:"+t2.length ()) ؛ // 11 قم بإزالة SPACE System.out.println (T2) ؛8.
سلسلة intern () السلسلة الأصلية العامة () ؛
سلسلة dd = سلسلة جديدة ("bb"). intern () ؛طريقة NERTER هي مكالمة أصلية ، ووظائفها هي العثور على كائنات ذات قيمة متساوية من خلال طريقة متساوية في التجمع الثابت في منطقة الطريقة.
إذا لم يتم العثور عليها ، افتح مساحة في حمام السباحة الثابت لتخزين السلسلة وإرجاع الإشارة إلى السلسلة المقابلة. خلاف ذلك ، إرجاع المرجع مباشرة إلى كائن السلسلة موجود بالفعل في التجمع الثابت.
يمكنك أيضًا فرض كائن الحرف الذي تم إنشاؤه للطريقة الجديدة لمعرفة ما إذا كان المسبح الثابت موجودًا بالفعل.
ضع الكود الثاني في المقدمة
// string a = new string ("AB1") ؛ // تغيير إلى سلسلة A = سلسلة جديدة ("AB1"). Intern () ؛والنتيجة صحيحة ، لأن العنوان الذي يشير إليه A يأتي من البركة الثابتة ، وسيقوم ثابت السلسلة الذي يشير إليه B إلى استدعاء هذه الطريقة بشكل افتراضي ، لذلك يشير كل من A و B إلى نفس مساحة العنوان.
int hash32 () private transient int hash32 = 0 ؛ int hash32 () {int h = hash32 ؛ إذا (0 == H) {// سباق بيانات غير ضار على Hash32 هنا. h = sun.misc.hashing.murmur3_32 (hashing_seed ، value ، 0 ، value.length) ؛ // تأكد من أن النتيجة ليست صفرًا لتجنب إعادة تقييم H = (0! = H)؟ H: 1 ؛ hash32 = h ؛ } العودة H ؛}في JDK1.7 ، عند استخدام فئة السلسلة كمفتاح ، لم تعد فئة التجميع المتعلقة بالتجمع تستخدم طريقة HashCode لإلغاء البيانات ، ولكنها تستخدم طريقة Hash32.
تستخدم هذه الطريقة الوقت الحالي للنظام ، وعنوان فئة السلسلة ، وعنوان فئة النظام ، وما إلى ذلك كعوامل لحساب بذرة التجزئة. من خلال بذرة التجزئة ، يتم الحصول على قيمة INT 32 بت من خلال بذرة التجزئة.
Public int length () {return value.length ؛} السلسلة العامة toString () {return this ؛} public boolean isempty () {return value.length == 0 ؛} char char char (int index) {if (index <0) || (index> = value.length)) } قيمة الإرجاع [الفهرس] ؛}ما سبق بعض الطرق الشائعة البسيطة.
لخص
كائنات السلسلة هي أنواع غير قابلة للتغيير. طرق السلسلة مع إرجاع نوع الإرجاع في كل مرة يتم إرجاع كائن سلسلة جديد ، باستثناء بعض الشروط المحددة لبعض الطرق لإرجاع نفسها.
ثلاث طرق لمقارنة كائنات السلسلة:
== مقارنة الذاكرة: قارن بشكل مباشر قيم الذاكرة التي أشار إليها المرجعين ، وهما دقيقة وموجزة ومباشرة.
يساوي مقارنة قيمة السلسلة: قارن ما إذا كانت القيم الحرفية للكائنين المشار إليها متساوية.
مقارنة العدد العددي لسلسلة Hashcode: العددية للسلاسل. هزليان مشار إليهما هو نفسه ، ولا تضمن الذاكرة هي نفسها ، ولا يتم ضمان القيم الحرفية لتكون هي نفسها.
فكرة تصميم سلسلة المسبح الثابت
1. النية الأصلية لتصميم المسبح الثابت للسلسلة
كل سلسلة هي كائن سلسلة ، وسيتم استخدام السلاسل بشكل متكرر في تطوير النظام. إذا تم إنشاؤها وتدميرها مثل الأشياء الأخرى ، فسيؤثر ذلك بشكل كبير على أداء البرنامج.
من أجل تحسين الأداء وتقليل النفقات العامة للذاكرة ، يتحسن JVM عند إنشاء سلاسل.
يتم فتح تجمع ثابت للسلسلة للسلاسل ، على غرار منطقة ذاكرة التخزين المؤقت
عند إنشاء سلسلة ثابتة ، حدد أولاً ما إذا كان هناك تجمع ثابت.
تقوم السلسلة بإرجاع مثيل مشار إليه ، ولا توجد ، وتستند إلى سلسلة ، ووضعها في المجمع.
أدرك الأساسيات
أساس تنفيذ هذا التحسين هو أن كل ثابت ثابت هو ثابت نهائي معدّل ، لذلك لا داعي للقلق بشأن تعارضات البيانات في التجمع الثابت.
يوجد جدول في مجموعة Global String الثابت التي تم إنشاؤها بواسطة مثيل وقت التشغيل ، والذي يحافظ دائمًا على مرجع لكل كائن سلسلة فريد في التجمع ، مما يعني أنها تشير دائمًا إلى الكائنات الموجودة في البركة الثابتة للسلسلة ، لذلك لن يتم جمع هذه الأوتار في التجمع الثابت بواسطة جامع القمامة.
كومة ، مكدس ، منطقة الطريقة
فهم حمامات سلسلة ثابتة ، انظر أولاً إلى منطقة طريقة المكدس
كومة
ما يتم تخزينه هو كائن ، كل كائن يحتوي على فئة مقابلة
يحتوي JVM فقط على منطقة كومة واحدة ويتم مشاركتها من قبل جميع المواضيع. لا توجد أنواع أساسية ومراجع للكائنات في الكومة ، ولكن فقط الكائن نفسه
يتم جمع الكائنات بواسطة جامع القمامة ، لذلك لا يلزم تحديد الحجم ودورة الحياة
كومة
يحتوي كل مؤشر ترابط على منطقة مكدس ، والتي تخزن فقط كائنات نوع البيانات الأساسية ومراجع الكائن المخصصة.
البيانات (النوع البدائي ومرجع الكائن) في كل مكدس خاص
يتم تقسيم المكدس إلى ثلاثة أجزاء: منطقة متغير النوع الأساسي ، وسياق بيئة التنفيذ ، ومنطقة تعليمات التشغيل (تخزين تعليمات التشغيل)
حجم البيانات ودورة الحياة مؤكدة ، وعندما لا تشير إلى هذه البيانات ، ستختفي البيانات.
منطقة الطريقة
يتم مشاركة المناطق الثابتة ، مثل أكوام ، من قبل جميع المواضيع
تحتوي منطقة الطريقة على عناصر فريدة من نوعها دائمًا في البرنامج بأكمله ، مثل المتغيرات الفئة والستاتية ؛
سلسلة ثابتة
يوجد تجمع ثابت السلسلة في منطقة الطريقة
الرمز: Stack Method areo Strings Strings
String str1 = "ABC" ؛ String str2 = "ABC" ؛ String str3 = "ABC" ؛ String str4 = new string ("ABC") ؛ String str5 = new string ("ABC") ؛أسئلة المقابلة
String Str4 = سلسلة جديدة ("ABC") كم عدد الكائنات التي يتم إنشاؤها؟
الانقسام: str4 = ، new string () ، "ABC"
يمكنك إنشاء كائن جديد من خلال طريقة جديدة. تنشئ الطريقة الجديدة كائنًا تم إنشاءه ولن يذهب إلى تجمع ثابت للعثور على ما إذا كان موجودًا بالفعل. طالما جديد ، سيتم إنشاء كائن جديد.
"ABC" كل سلسلة هي كائن سلسلة. إذا لم يكن هناك في تجمع ثابت ، فسيتم إنشاء كائن جديد ووضعه في البركة الثابتة. خلاف ذلك ، سيتم إرجاع مرجع الكائن.
قم بتعيين عنوان الكائن إلى STR4 وإنشاء مرجع
لذلك ، إذا لم يكن هناك "ABC" حرفيًا في التجمع الثابت ، قم بإنشاء كائنين ، وإلا قم بإنشاء كائن واحد ، وإنشاء مرجع
String str1 = سلسلة جديدة ("A"+"B") ؛ كم عدد الكائنات التي سيتم إنشاؤها؟ String str2 = سلسلة جديدة ("ABC") + "ABC" ؛ كم عدد الكائنات التي سيتم إنشاؤها؟
التحليل الشامل المذكور أعلاه لرمز مصدر سلسلة Java و Bool الثابت هو كل المحتوى الذي أشاركه معك. آمل أن تتمكن من إعطائك مرجعًا وآمل أن تتمكن من دعم wulin.com أكثر.