Java / الأساسي / الدرس 5
المصفوفات والنصوص وحدود المحارف
تعامل مع المتتاليات مع تمييز حجم المصفوفة الثابت وثبات String وهوية المرجع ومساواة المحتوى ووحدات Unicode.
في هذه الصفحة
أهداف الدرس
- اجتياز المصفوفة دون فهرس غير صالح.
- مقارنة المحتوى وبناء النص بكفاءة.
- اختيار قواعد الطول والتحليل المناسبة.
اعرف ما تملكه المصفوفة
للمصفوفة طول ثابت عند الإنشاء ومواقع من صفر إلى length-1. تحتوي int قيماً أولية وتحتوي String مراجع قد تكون null. لا ينشئ بناء المصفوفة كل كائن مرجوع إليه. ميّز وجود المصفوفة وطولها وصلاحية عناصرها قبل الاستخدام.
يشترك متغيران أُسند أحدهما للآخر في المرجع نفسه. تنشئ Arrays.copyOf مصفوفة جديدة لكن نسخ المراجع سطحي وتبقى العناصر المتغيرة مشتركة. استخدم for المحسنة للقيم والفهرسية للمواضع. ولا يغني أي اجتياز عن تحديد سلوك الفراغ.
راقب التخزين المستقل بعد النسخ
ينسخ المثال ثلاثة عناصر أولية ويغير النسخة ويجمع الأصل. يبقى الأصل2 و4 و6، فمجموعه12 وأول عنصر من النسخة99. يثبت ذلك اختلاف تخزين العناصر لا ضمان نسخة عميقة لكل شبكة كائنات.
اختر للمجموع نوعاً يكفي المجال. قد يتجاوز int المدى مع ملايين عناصر int صالحة منفردة. تحتاج null والفراغ والحجم المفرط عقوداً صريحة. راع حجم البيانات ومتطلبات التعديل عند تقييم كلفة النسخ بدلاً من تجنبه تلقائياً.
public class Main {
public static void main(String[] args) throws Exception {
int[] original={2,4,6};
int[] copy=java.util.Arrays.copyOf(original,original.length);
copy[0]=99;
int total=0;
for (int value:original) { total+=value; }
System.out.println(total);
System.out.println(copy[0]);
}
}
12
99
لا يغير copy[0] عنصر الأصل، وتزور الحلقة المحسنة كل قيمة أصلية مرة.
قارن المحتوى لا المراجع
String ثابتة؛ تعيد الدوال التي تبدو معدلة نصاً آخر. تقارن == هوية المرجع وتقارن equals المحتوى. قد يجعل تخزين الثوابت المشترك مقارنة الهوية تبدو صحيحة في مثال صغير ثم تفشل لإدخال وقت التشغيل. ينشئ المثال كائناً مستقلاً عمداً كيلا يخفي المرجع المشترك الفرق.
حدد سياسة null: تقارن Objects.equals مرجعين اختياريين بأمان، وتتطلب a.equals(b) مستقبلاً غير null. تختلف مساواة حالة الأحرف عن الفرز المحلي ولا يصح تخمينهما من اسم عرض. وثّق تطبيع رموز البروتوكول ولغته بدلاً من تغيير نص البشر اعتباطياً.
public class Main {
public static void main(String[] args) throws Exception {
String first="java";
String second=new String("java");
System.out.println(first==second);
System.out.println(first.equals(second));
}
}
false
true
ينشئ new كائناً مختلفاً لكن محتواه يساوي الثابت؛ فتجيب المقارنتان عن سؤالين مختلفين.
اختر وحدة عملية النص الصحيحة
تحسب String.length وحدات UTF-16. قد يشغل رمز تعبيري موضعين، فلا تعيد charAt نقطة Unicode كاملة دائماً. تدعم codePointCount وcodePoints التعامل بالنقاط، وقد تحتاج الوحدة المرئية طبقة إضافية. عبارة «عشرة محارف» ناقصة حتى تحديد الوحدة.
تضم substring فهرس البداية وتستبعد النهاية. تحقق من0 <= start <= end <= length؛ وتصح نهاية تساوي length. قد يقطع فهرس char اعتباطي زوجاً بديلاً. فك البايتات الخارجية بترميز صريح مثل UTF-8 وحدد التعامل مع التالف بدلاً من ترميز الجهاز الافتراضي.
افصل بناء النص عن تأويله
لبناء متكرر داخل حلقة يمكن لـ StringBuilder جمع الأجزاء دون تعبير متكرر عن استبدال النص كله. وبما أنه متغير فلا تشاركه بين الخيوط دون حماية. فضّل String.join لعملية فاصل بسيطة إذا أوضحت القصد. ابدأ بالقراءة ثم قس العمل المهم قبل ادعاء السرعة.
التحليل عملية حد بصيغة ومدى. ترفض Integer.parseInt النص غير العددي أو الخارج عن المدى ولا تتحقق من قاعدة كالمخزون الموجب. حدد قبول الفراغات قبل التحليل واحفظ الأصل في تشخيص مقيد. لا تستبدل كل فشل بصفر صامت كيلا تحول غير الصالح إلى نتيجة معقولة.
الأخطاء الشائعة وإصلاحها
ArrayIndexOutOfBoundsException
- لماذا يحدث؟
- الفهرس خارج المجال نصف المفتوح.
- كيف تصلحه؟
- تحقق منه واستخدم < length.
- كيف تتجنب تكراره؟
- اختبر الفراغ وآخر عنصر.
Equal strings compare false with ==
- لماذا يحدث؟
- استُخدمت هوية المرجع للمحتوى.
- كيف تصلحه؟
- استخدم equals أوObjects.equals وفق null.
- كيف تتجنب تكراره؟
- اختبر نصوصاً أنشئت مستقلة.
NumberFormatException
- لماذا يحدث؟
- النص تالف أو خارج مدى المحلل.
- كيف تصلحه؟
- ارفضه أو أبلغ عند حد الإدخال.
- كيف تتجنب تكراره؟
- اختبر الفراغ والإشارات والتجاوز وحدود المجال.
اختبر فهمك
1. يشير متغيران للمصفوفة نفسها ويغير أحدهما العنصر صفر. ماذا يرى الآخر؟
اعرض الحل المشروح
يرى التعديل لاشتراكهما في مصفوفة متغيرة. للنسخة الأولية تخزين مستقل؛ وتظل كائنات عناصر نسخة المراجع السطحية مشتركة.
2. لماذا تزيد length() على codePointCount؟
اعرض الحل المشروح
تستخدم النقاط الإضافية زوجاً بديلاً بوحدتي UTF-16. تحسب الأولى الوحدات والثانية النقاط، ولا يساوي أيهما دائماً عدد الوحدات المرئية؛ اختر مقياس المنتج.
أهم ما تعلمته
- للمصفوفة طول ثابت وفهرسة صفرية نصف مفتوحة.
- تختلف هوية String ومحتواها ووحداتها.
- التحليل والتحقق التجاري خطوتان منفصلتان.