JavaRush /مدونة جافا /Random-AR /الترجمة: إنشاء كائنات سلسلة في Java - باستخدام "" أو المُ...
FellowSparrow
مستوى
Lvov

الترجمة: إنشاء كائنات سلسلة في Java - باستخدام "" أو المُنشئ؟

نشرت في المجموعة
الأصل: إنشاء سلسلة Java باستخدام "" أو المُنشئ؟ بواسطة X Wang الترجمة: إنشاء كائنات سلسلة في جافا - الاستخدامفي Java، يمكن إنشاء سلسلة باستخدام طريقتين:
String x = "abc";
String y = new String("abc");
ما الفرق بين استخدام علامات الاقتباس المزدوجة واستخدام المُنشئ؟

1. الاقتباسات المزدوجة مقابل الاقتباسات المزدوجة البناء

يمكن الإجابة على هذا السؤال من خلال النظر إلى مثالين بسيطين. مثال 1:
String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
a==bصحيح لأنهما يشيران إلى نفس الكائن - سلسلة تم تعريفها كسلسلة حرفية (سلسلة حرفية أدناه) في منطقة الطريقة (نحيل القارئ إلى المصدر الموجود على موردنا: أفضل 8 aمخططات لفهم Java ، الرسم البياني 8). عندما يتم إنشاء نفس السلسلة الحرفية أكثر من مرة، يتم تخزين نسخة واحدة فقط من السلسلة في الذاكرة، مثيل واحد فقط منها (في حالتنا "abcd"). وهذا ما يسمى "تدريب السلسلة". يتم تلقائيًا إدخال جميع ثوابت السلسلة التي تتم معالجتها في وقت الترجمة في Java. مثال 2: b
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True
c==dخطأ لأنها cتشير dإلى كائنين مختلفين في الذاكرة (في الكومة). الكائنات المختلفة لها دائمًا مراجع مختلفة. يوضح هذا الرسم البياني الحالتين الموضحتين أعلاه: الترجمة: إنشاء كائنات سلسلة في جافا - الاستخدام

2. سلاسل التدريب في مرحلة تنفيذ البرنامج

يشكر المؤلف LukasEder (التعليق أدناه خاص به): يمكن أن يحدث تدريب السلسلة أيضًا أثناء تنفيذ البرنامج، حتى لو تم إنشاء سلسلتين باستخدام المنشئات:
String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d);  // Now true
System.out.println(c.equals(d)); // True

3. متى تستخدم علامات الاقتباس المزدوجة ومتى تستخدم المنشئات

نظرًا لأن "abcd" الحرفي دائمًا ما يكون من النوع String، فإن استخدام المُنشئ سيؤدي إلى إنشاء كائن إضافي غير ضروري. لذلك يجب استخدام علامات الاقتباس المزدوجة إذا كنت بحاجة فقط إلى إنشاء سلسلة. إذا كنت تريد بالفعل إنشاء كائن جديد في الكومة، فيجب عليك استخدام المُنشئ. تظهر حالات الاستخدام هنا (الأصلية) . (أقدم النص المترجم أدناه. لكنني ما زلت أوصي بشدة بالتعرف على كود المعلقين على هذا الرابط.)

طريقة السلسلة الفرعية () في JDK 6 وJDK 7

طريقة السلسلة الفرعية () في JDK 6 وJDK 7substring(int beginIndex, int endIndex) بواسطة X Wang تختلف الطريقة في JDK 6 وJDK 7. يمكن أن تساعدك معرفة هذه الاختلافات في استخدام هذه الطريقة بشكل أفضل. ولتسهيل القراءة، substring()سنقصد أدناه بناء الجملة الكامل، أي. substring(int beginIndex, int endIndex).

1. ماذا تفعل السلسلة الفرعية ()؟

تقوم الطريقة substring(int beginIndex, int endIndex)بإرجاع سلسلة تبدأ برقم الحرف beginIndexوتنتهي برقم الحرف endIndex-1.
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
انتاج:
bc

2. ماذا يحدث عند استدعاء السلسلة الفرعية ()؟

ربما تعلم أنه بسبب الثبات x، عند تعيين x نتيجة لـ x.substring(1,3)، xفإنه يشير إلى صف جديد تمامًا (انظر الرسم البياني): الترجمة: إنشاء كائنات سلسلة في جافا - الاستخدامومع ذلك، هذا الرسم البياني ليس صحيحًا تمامًا؛ لا يوضح ما يحدث بالفعل في الكومة. ما يحدث فعليًا عند الاتصال substring()يختلف في JDK 6 وJDK 7.

3. سلسلة فرعية () في JDK 6

نوع السلسلة مدعوم بنوع الصفيف char. في JDK 6، يحتوي الفصل Stringعلى 3 حقول: char value[], int offset, int count. يتم استخدامها لتخزين المصفوفة الفعلية من الأحرف، وفهرس الحرف الأول في المصفوفة، وعدد الأحرف في السطر. عندما يتم استدعاء الأسلوب substring()، فإنه يقوم بإنشاء صف جديد، ولكن قيمة المتغير لا تزال تشير إلى نفس المصفوفة في الكومة. الفرق بين سلسلتين هو عدد الأحرف وقيمة الفهرس لحرف البداية في المصفوفة. الترجمة: إنشاء كائنات سلسلة في جافا - الاستخدامالكود أدناه مبسط ويحتوي فقط على الأساسيات لشرح المشكلة.
//JDK 6
String(int offset, int count, char value[]) {
	this.value = value;
	this.offset = offset;
	this.count = count;
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

4. المشكلة الناجمة عن السلسلة الفرعية () في JDK 6

إذا كان لديك سلسلة طويلة جدًا، لكنك تحتاج فقط إلى جزء صغير منها، والذي تحصل عليه في كل مرة تستخدم فيها substring(). سيؤدي هذا إلى حدوث مشكلات في التنفيذ، نظرًا لأنك تحتاج فقط إلى جزء صغير، ولكن لا يزال يتعين عليك تخزين السلسلة بأكملها. بالنسبة لـ JDK 6، الحل هو الكود أدناه، والذي سيحول السلسلة إلى سلسلة فرعية حقيقية:
x = x.substring(x, y) + ""
قام المستخدم STepeR بصياغة سؤال (انظر تعليقه)، ويبدو أنه من الضروري إضافة النقطة 4. "المشكلة التي حدثت substring()في JDK 6" هي مثال أكثر شمولاً. آمل أن يكون هذا هو الجواب وأن يساعد الآخرين على معرفة المشكلة بسرعة. إليك الكود:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
لذا، في JDK 7 b، فإن الكائنات сمن النوع a Stringالتي تم إنشاؤها عن طريق استدعاء أسلوب substring()على كائن من النوع a Stringستشير إلى صفيفين تم إنشاؤهما حديثًا في الكومة - Lfor b, ongLfor c. سيتم تخزين هذين الصفيفين الجديدين في الكومة مع المصفوفة الأصلية aLongLongStringالمشار إليها بواسطة a. أولئك. المصفوفة الأصلية لا تختفي في أي مكان. لنعد الآن إلى JDK 6. في JDK 6، تحتوي الكومة على مصفوفة واحدة aLongLongString. بعد تنفيذ أسطر التعليمات البرمجية
String b = a.substring(1, 2);
String c = a.substring(2, 6);
bتشير الكائنات cإلى نفس المصفوفة في الكومة، المقابلة للكائن a: b- إلى العناصر من الفهرس الأول إلى الثاني، c- إلى العناصر من الفهرس الثاني إلى السادس (يبدأ الترقيم من 0، تذكير). أولئك. من الواضح أن أي وصول إضافي إلى المتغيرات bأو c في JDK 6 سيؤدي في الواقع إلى "احتساب" العناصر المطلوبة من المصفوفة الأصلية في الكومة. في JDK 7، أي وصول إضافي إلى المتغيرات bأو لغة c سوف يتسبب في الوصول إلى المصفوفات الأصغر الضرورية التي تم إنشاؤها بالفعل و"المباشرة" في الكومة. أولئك. من الواضح أن JDK 7 يستخدم ذاكرة أكبر فعليًا في مثل هذه المواقف. ولكن دعونا نتخيل خيارًا ممكنًا: يتم تعيين سلاسل فرعية معينة من المتغير للمتغيرات b، وفي المستقبل يستخدمها الجميع فقط - الكائنات و . لم يعد أحد يصل إلى المتغير ببساطة، ولا توجد إشارات إليه (هذا ما يعنيه كاتب المقال). نتيجة لذلك، في وقت ما، يتم تشغيل أداة تجميع البيانات المهملة، و(في الشكل الأكثر عمومية، بالطبع) نحصل على حالتين مختلفتين: JDK 6 : تم تدمير الكائن (تجميع البيانات المهملة) ، ولكن - المصفوفة الضخمة الأصلية في الكومة حي. يتم استخدامه باستمرار و . JDK 7: تم تدمير الكائن a مع المصفوفة الأصلية في الكومة. هذه هي النقطة في JDK 6 التي يمكن أن تؤدي إلى تسرب الذاكرة. cabcabc

5. سلسلة فرعية () في JDK 7

تم تحسين الطريقة في JDK 7. في JDK 7 substring()يقوم بالفعل بإنشاء مصفوفة جديدة على الكومة. الترجمة: إنشاء كائنات سلسلة في جافا - الاستخدام
//JDK 7
public String(char value[], int offset, int count) {
	//check boundary
	this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	int subLen = endIndex - beginIndex;
	return new String(value, beginIndex, subLen);
}
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION