JavaRush /جاوا بلاگ /Random-UR /ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1]
Vonorim
سطح

ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1]

گروپ میں شائع ہوا۔
یہ مضمون کلیکشن فریم ورک سے ArrayList کلاس پر تفصیلی نظر ڈالے گا، جسے سمجھنا شاید سب سے آسان ہے، اس حقیقت کی وجہ سے کہ یہ باقاعدہ صف پر مبنی ہے۔ انٹرویو میں آپ سے یقینی طور پر اس کلاس اور جاوا میں اس کے نفاذ کے بارے میں ایک سوال پوچھا جائے گا۔ دوسرے حصے میں ہم بقیہ طریقوں کا تجزیہ کریں گے اور نمبروں کے لیے متحرک صف کا اپنا اپنا نفاذ لکھیں گے۔ ArrayList کلاس AbstractList کلاس سے وراثت میں ملتی ہے اور درج ذیل انٹرفیس کو لاگو کرتی ہے: List, RandomAccess، Cloneable، Serializable۔ ArrayList کلاس کا تفصیلی تجزیہ [Part 2] ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 1 ArrayList کلاس متحرک صفوں کو سپورٹ کرتی ہے جنہیں ضرورت کے مطابق بڑھایا جا سکتا ہے۔ اس کی ضرورت اور تاثیر کی وضاحت اس حقیقت سے ہوتی ہے کہ ایک باقاعدہ صف کی ایک مقررہ لمبائی ہوتی ہے: ایک بار جب یہ بن جاتی ہے، تو یہ بڑھ نہیں سکتی یا سکڑ نہیں سکتی، جو پابندیاں عائد کرتی ہے اگر یہ معلوم نہ ہو کہ کتنی بڑی صف کی ضرورت ہوگی۔ بنیادی طور پر، ArrayList کلاس آبجیکٹ حوالہ جات کی ایک متغیر لمبائی کی فہرست ہے۔ یہ سمجھنا ضروری ہے کہ اندرونی صف کا سائز (خلیوں کی تعداد) خود بخود کم نہیں ہوتا ہے جب عناصر کو اس سے ہٹا دیا جاتا ہے۔ درحقیقت، متغیر کی قدر size، جو کہ صف میں موجود عناصر کی تعداد کو ظاہر کرتی ہے، کم ہو گئی ہے۔ ہم کہتے ہیں کہ ہم ArrayList کلاس کا ایک نیا آبجیکٹ بناتے ہیں اور اس میں 5 عناصر شامل کرتے ہیں۔ پہلے سے طے شدہ طور پر، 10 عناصر کی ایک صف بنائی جاتی ہے۔ اس صورت میں، ہمارے آبجیکٹ کی نام نہاد صلاحیت (سائز/حجم) 10 کے برابر ہوگی، لیکن متغیر کی قدر sizeپانچ کے برابر ہوگی۔ اور جب ہم عناصر کو حذف کرتے ہیں تو ہم متغیر کی قدر میں تبدیلیاں دیکھتے ہیں size، کیونکہ ہم .lengthArrayList کلاس کی اندرونی صف تک رسائی حاصل نہیں کر سکتے اور اس کی لمبائی کا پتہ نہیں لگا سکتے۔ سائز کو ایک اضافی طریقہ استعمال کرتے ہوئے کم کیا جا سکتا ہے trimToSize()، جس پر بعد میں بات کی جائے گی۔ آئیے کلاس فیلڈز کو دیکھتے ہیں۔
  • متحرک صف کے پہلے سے طے شدہ حجم کے لیے ذمہ دار فیلڈ:

    private static final int DEFAULT_CAPACITY = 10

    جب کوئی نئی آبجیکٹ نئی ArrayList<>() (پیرامیٹر کے بغیر کنسٹرکٹر) بناتے ہیں تو اندر 10 عناصر کی ایک صف بنائی جاتی ہے۔

  • ایک فیلڈ جس میں مجموعہ کے تمام عناصر محفوظ ہیں:

    transient Object[] elementData

    کلیدی لفظ کے ساتھ نشان زد transient- معیاری سیریلائزیشن الگورتھم استعمال کرتے وقت فیلڈ کو بائٹ اسٹریم پر نہیں لکھا جاتا ہے۔ یہ بات قابل غور ہے کہ فیلڈ کو مطلوبہ الفاظ سے نشان زد نہیں کیا گیا ہے private، لیکن یہ نیسٹڈ کلاسز (مثال کے طور پر، سب لسٹ) سے اس فیلڈ تک رسائی کو آسان بنانے کے لیے کیا گیا ہے۔

  • ایک کاؤنٹر فیلڈ جو اصل میں صف میں عناصر کی تعداد کو ذخیرہ کرتا ہے:

    private int size

    داخل کرنے اور حذف کرنے جیسی کارروائیوں کو انجام دیتے وقت قدر میں اضافہ/کمی ہوتی ہے۔

کلاس میں مزید 3 فیلڈز ہیں، لیکن بنیادی طور پر وہ اضافی ہیں، اس لیے ان پر غور کرنے کا کوئی فائدہ نہیں۔ کلاس میں تین کنسٹرکٹرز ہیں:
  1. public ArrayList()- 10 عناصر کی ایک خالی فہرست سرنی بناتا ہے۔
  2. public ArrayList(Collection < ? extends E > c)- پاس شدہ مجموعہ کے عناصر کے ساتھ شروع کردہ فہرست کی صف بناتا ہے (اگر ہم کچھ مجموعہ کی بنیاد پر ایک نئی ArrayList بنانا چاہتے ہیں)؛
  3. public ArrayList(int initialCapacity)- ابتدائی صلاحیت کے ساتھ فہرست کی صف بناتا ہے۔ اگر پاس شدہ پیرامیٹر ابتدائی صلاحیت 0 سے زیادہ ہے، تو مخصوص سائز کی ایک صف بنائی جاتی ہے (اندرونی فیلڈ عنصر ڈیٹا کو ایک نئی صف کے لیے ایک لنک تفویض کیا جاتا ہے جس کی قسم Object of size initialCapacity ہے)۔ اگر پیرامیٹر 0 ہے، تو ایک خالی صف بنائی جاتی ہے۔ اگر متعین پیرامیٹر 0 سے کم ہے، تو پھر ایک IllegalArgumentException پھینک دیا جاتا ہے۔
آبجیکٹ بنانا
List < String> list = new ArrayList<>();
نئی تخلیق کردہ آبجیکٹ listمیں پراپرٹیز (فیلڈز) elementDataاور size. ایک ویلیو اسٹور ہمارے معاملے میں elementDataایک مخصوص قسم کی صف سے زیادہ کچھ نہیں ہے (عام - میں بیان کیا گیا ہے ) ۔ اگر پیرامیٹرز کے بغیر کنسٹرکٹر کو بلایا جاتا ہے، تو بطور ڈیفالٹ قسم کے 10 عناصر کی ایک صف بنائی جائے گی (یقیناً قسم پر کاسٹ کرنے کے ساتھ)۔ عناصر کو شامل کرنا کلاسیکی طور پر فہرست کی صف میں عناصر کو شامل کرنا کے اوور لوڈ شدہ مختلف حالتوں کا استعمال کرتے ہوئے کیا جاتا ہے ۔ <>String[]ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 2add()
public boolean add(E элемент)
ٹھیک ہے، آئیے شامل کریں: list.add("0"); ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 3اس طریقہ کے اندر، طریقہ کا ایک اوورلوڈ ورژن add()کہا جاتا ہے، جس پر نشان لگایا گیا ہے private، جس کے نتیجے میں ان پٹ کے طور پر تین پیرامیٹرز لگتے ہیں: جو عنصر شامل کیا جانا ہے، اندرونی صف اور اس کا سائز۔ نجی طریقہ میں، ایک چیک ہوتا ہے: اگر پاس شدہ سائز کا پیرامیٹر اندرونی صف کی لمبائی کے برابر ہے (یعنی سرنی بھرا ہوا ہے)، تو صف کو طریقہ کار کا نتیجہ تفویض کیا جاتا ہے grow(int minCapacity)(فیلڈ کی موجودہ قیمت سائز + 1 کو طریقہ کار میں منتقل کیا جاتا ہے، کیونکہ شامل کیے جانے والے عنصر کو مدنظر رکھنا ضروری ہے)، جس میں اندرونی صف کو اصل صف کے عناصر کو کاپی کرکے حاصل کردہ نئی تخلیق کردہ صف کا لنک تفویض کیا جاتا ہے:
Arrays.copyOf(elementData, newCapacity(minCapacity))
طریقہ کار کے دوسرے پیرامیٹر کے طور پر، copyOfہم اس طریقہ کار کے نتیجے کی نشاندہی کرتے ہیں newCapacity(int minCapacity)، جس کے اندر نئی صف کے سائز کا حساب لگایا جاتا ہے۔ اس کا حساب درج ذیل فارمولے سے کیا جاتا ہے: int newCapacity = oldCapacity + (oldCapacity >> 1) پہلے سے طے شدہ سائز کے ساتھ ایک صف کے لیے، درج ذیل درست ہوں گے: >> 1- بٹ وائز ایک کے ذریعے دائیں طرف شفٹ کریں (ایک آپریٹر جو تعداد کو اس کے نصف تک کم کرتا ہے)۔ بنیادی طور پر، اس کا مطلب ہے 1 کی طاقت کو 2 سے تقسیم کرنا۔ اس سے پتہ چلتا ہے کہ ہم 10 کو 2 سے تقسیم کرتے ہیں اور 10 کا اضافہ کرتے ہیں۔ کل، صف کی نئی گنجائش 15 ہے، لیکن چونکہ ہم 11ویں عنصر کو شامل کر رہے ہیں، تو 15 + 1 = 16. آئیے اپنی فہرست پر واپس آتے ہیں اور فرض کریں کہ ہم نے پہلے ہی اس میں 10 عناصر کا اضافہ کیا ہے اور 11 کو شامل کرنے کی کوشش کریں۔ چیک ظاہر کرے گا کہ صف میں کوئی جگہ نہیں ہے۔ اس کے مطابق، ایک نئی صف بنائی جاتی ہے اور اسے کہا جاتا ہے Arrays.copyOf، جو اندرونی طور پر سسٹم کا طریقہ استعمال کرتا ہے System.arraycopy()۔ ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 4ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 5یا یہاں جاوا رش کے ایک مضمون سے واضح مثال ہے: ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 6ان تمام جانچ پڑتال کے بعد اور اگر ضروری ہو تو سرنی کے سائز میں اضافہ کرنے کے بعد، پھر نجی طریقہ میں add()صف کے آخر میں ایک نیا عنصر شامل کیا جاتا ہے، اور موجودہ پیرامیٹر میں sizeایک اضافہ کیا جاتا ہے۔ . پرانی صف پر بعد میں کوڑا اٹھانے والے کے ذریعے کارروائی کی جائے گی۔ اس طرح ایک متحرک صف کام کرتی ہے: جب ہم عناصر کو شامل کرتے ہیں، تو ہم چیک کرتے ہیں کہ آیا اس میں ابھی بھی گنجائش موجود ہے یا نہیں۔ اگر اسپیس ہے، تو ہم صرف عنصر کو صف کے آخر میں شامل کرتے ہیں۔ اختتام کا مطلب صف میں آخری سیل نہیں ہے، بلکہ وہ سیل جو قدر سے مطابقت رکھتا ہے size۔ ہم نے صف میں پہلا عنصر شامل کیا؛ یہ انڈیکس [0] کے ساتھ سیل میں رکھا گیا ہے۔ فیلڈ ویلیو sizeمیں ایک اور = 1 کا اضافہ ہوا ہے۔ ہم اگلا عنصر شامل کرتے ہیں: ہم دیکھتے ہیں کہ size = 1، اس کے مطابق ہم عنصر کو انڈیکس [1] اور اسی طرح سیل میں رکھتے ہیں۔ دو پیرامیٹرز کے ساتھ طریقہ کار کا ایک اوورلوڈ ورژن ہے:
public void add(int index, E element)
ہم سیل کی پوزیشن (انڈیکس) بتا سکتے ہیں جہاں ہم عنصر شامل کرنا چاہتے ہیں۔ سب سے پہلے، مخصوص اشاریہ کی قیمت کی درستگی کی جانچ پڑتال کی جاتی ہے، کیونکہ اس بات کا امکان موجود ہے کہ ایک غلط اشاریہ متعین کیا جائے گا، جو ایک ایسے خلیے کی طرف اشارہ کرے گا جہاں کچھ نہیں ہے، یا جو محض موجود نہیں ہے۔ اشاریہ جات کی جانچ کرنا: index > size || index < 0- اگر مخصوص انڈیکس صف کے موجودہ سائز سے بڑا ہے یا یہ 0 سے کم ہے، تو ایک استثناء پھینک دیا جاتا ہے IndexOutOfBoundsException۔ پھر، اگر ضروری ہو تو، اوپر کی مثال کی طرح، صف کا سائز بڑھا دیا جاتا ہے۔ آپ نے شاید سنا ہوگا کہ ایک صف میں شامل/ہٹانے کے عمل کے دوران، کچھ کہیں (یا تو دائیں یا بائیں) شفٹ ہو جاتا ہے۔ لہذا، شفٹ صف کو کاپی کرکے انجام دیا جاتا ہے: System.arraycopy(elementData, index, elementData, index + 1, s - index); مخصوص انڈیکس کے دائیں جانب واقع تمام عناصر کو ایک پوزیشن دائیں (انڈیکس+1) منتقل کردیا جائے گا۔ اور اس کے بعد ہی مخصوص انڈیکس میں داخلی صف میں ایک نیا عنصر شامل کیا جاتا ہے۔ چونکہ ہم نے صف کا کچھ حصہ ایک ایک کرکے دائیں طرف منتقل کر دیا ہے (نئی صف نہیں بنائی گئی ہے)، اس لیے ہمیں جس سیل کی ضرورت ہے وہ لکھنے کے لیے آزاد ہو گا۔ پرانی صف کا لنک مٹا دیا گیا ہے اور مستقبل میں اسے کوڑا اٹھانے والے کے قبضے میں لے لیا جائے گا۔ "maserati" کو سیل میں چسپاں کریں [3]، جو پہلے ہی زیر قبضہ ہے:
ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 7
اس طرح، جب ایک عنصر کو انڈیکس میں داخل کیا جاتا ہے اور صف میں کوئی خالی جگہ نہیں ہوتی ہے، تو کال System.arraycopy()دو بار ہو گی: پہلی میں grow()، دوسری خود طریقہ کار میں add(index, value)، جو پورے ایڈنگ آپریشن کی رفتار کو واضح طور پر متاثر کرے گی۔ نتیجے کے طور پر، جب اندرونی صف میں کوئی دوسرا عنصر لکھنا ضروری ہو، لیکن وہاں کوئی جگہ نہ ہو، تو ArrayList کے اندر یہی ہوتا ہے:
  • ایک نئی صف اصل سے 1.5 گنا بڑے سائز کے ساتھ ایک عنصر کے ساتھ بنائی گئی ہے۔
  • پرانی صف کے تمام عناصر کو نئی صف میں کاپی کیا جاتا ہے۔
  • نئی صف کو ArrayList آبجیکٹ کے اندرونی متغیر میں محفوظ کیا جاتا ہے، اور پرانی صف کو ردی کی ٹوکری میں قرار دیا جاتا ہے۔
ArrayList قسم کی اشیاء کی صلاحیت کو طریقہ استعمال کرتے ہوئے دستی طور پر بڑھایا جا سکتا ہے:
public void ensureCapacity(int minCapacity)
پہلے سے صف کی گنجائش بڑھا کر، آپ بعد میں RAM کی اضافی دوبارہ جگہ سے بچ سکتے ہیں۔ یہ طریقہ داخلی صف کے سائز کو بڑھاتا ہے تاکہ عناصر کی تعداد کو ایڈجسٹ کیا جا سکے minCapacity۔ طریقہ ensureCapacity()فیلڈ کو متاثر نہیں کرتا size، یہ capacityاندرونی صف (کے سائز) کو متاثر کرتا ہے۔ ایک بار پھر میں اس بات پر زور دیتا ہوں کہ sizeدونوں capacityمختلف چیزیں ہیں اور ان میں الجھنا بہت ضروری ہے! اگر آپ بنیادی صف کے سائز کو کم کرنا چاہتے ہیں جہاں سے ArrayList اصل میں ذخیرہ شدہ عناصر کی موجودہ تعداد تک بنی ہے، آپ کو کال کرنا چاہیے trimToSize()۔ مجموعہ سے عناصر کو ہٹانے کے بعد، size()یہ اصل میں موجود عناصر کی تعداد دکھائے گا، اور capacityکم نہیں ہوگا! فرض کریں: ہم نے 100 عناصر داخل کیے، پہلے 50 کو حذف کر دیا، sizeیہ 50 کے برابر ہو جائے گا، اور اس طرح capacityیہ 100 رہے گا۔ کم کرنے کے لیے اور capacity، ہمیں طریقہ استعمال کرنے کی ضرورت ہے trimToSize()، جو ہماری پوری صلاحیت کو موجودہ سائز کے مطابق بناتا ہے۔ یہ کیسے موزوں ہوگا؟ ہماری صف کو کاپی کرتا ہے تاکہ کوئی خالی خلیات باقی نہ رہیں (نئی صف کی لمبائی صرف سائز فیلڈ کے برابر ہے)۔
ArrayList کلاس کا تفصیلی تجزیہ [حصہ 1] - 8
آپ کا استعمال کرتے ہوئے ہمارے مجموعہ میں عناصر بھی شامل کر سکتے ہیں addAll۔
public boolean addAll(Collection< ? extends E> c)
public boolean addAll(int index, Collection< ? extends E> collection);
پہلا آپشن آپ کو میتھڈ پیرامیٹر (مثال کے طور پر ایک اور شیٹ) میں بیان کردہ کلیکشن سے اصل کلیکشن (آخر میں داخل کریں) میں شامل کرنے کی اجازت دیتا ہے جس کے لیے میتھڈ کال کی گئی تھی۔ پاس کردہ مجموعہ (یہ ایک سیٹ بھی ہوسکتا ہے) کا استعمال کرتے ہوئے ایک صف میں تبدیل ہوجاتا ہے toArray()۔ قدرتی طور پر، شامل کرنے کا عمل بھی کاپی کا استعمال کرتے ہوئے کیا جاتا ہے۔ دوسرا collectionفہرست میں تمام عناصر کو شامل کرنا ہے، index سے شروع ہو کر index۔ اس صورت میں، فہرست میں عناصر کی تعداد کے حساب سے تمام عناصر دائیں طرف شفٹ ہو جائیں گے collection۔ عناصر کو ہٹانا پہلے، آئیے ایک ArrayList سے عناصر کو ہٹانے کے لیے کلاسک آپشنز کو دیکھتے ہیں۔
public E remove(int index)
انڈیکس کے ذریعے حذف کرنے کا عمل انجام دیتا ہے اور تمام بعد والے (مخصوص انڈیکس میں عنصر کے بعد) عناصر کو بائیں طرف شفٹ کرتا ہے، اس طرح "سوراخ" بند ہو جاتے ہیں۔ یہ حذف شدہ عنصر (E) کو بھی لوٹاتا ہے، جسے حذف کرنے سے پہلے ایک اضافی متغیر پر لکھا جاتا ہے، جس کی قیمت ہم میتھڈ کال کے نتیجے میں حاصل کرتے ہیں۔ یہ سمجھنے کے لیے کہ E کیا ہے، آپ کو نام نہاد عام اقسام سے واقف ہونے کی ضرورت ہوگی۔ اشارے E اشارہ کرتا ہے کہ طریقہ ڈیٹا کی قسم کو واپس کرتا ہے جو ArrayList آبجیکٹ بناتے وقت بیان کیا گیا تھا (یاد رکھیں: اس List <String> listکے مطابق، اس صورت میں، E کو "متبادل" کیا جائے گا String)۔ ایک عام فہم کے لیے، میں پرزور مشورہ دیتا ہوں کہ آپ اپنے آپ کو عام اقسام سے واقف کر لیں۔ درج کردہ انڈیکس کی درستگی کی جانچ پڑتال کی جاتی ہے، اور پھر طریقہ کے اندر، عنصر کو مکمل طور پر حذف نہیں کیا جاتا ہے، لیکن ایک نجی طریقہ کو کہا جاتا ہے fastRemove(Object[] es, int i)، جس میں حذف پہلے ہی واقع ہوتا ہے۔ ہم اپنی صف اور مخصوص انڈیکس کو ان پٹ کے طور پر طریقہ میں منتقل کرتے ہیں۔ عناصر کو استعمال کرتے ہوئے کاپی کیا جاتا ہے System.arraycopy()، صف کا سائز کم کر دیا جاتا ہے، اور پھر ہم آخری عنصر کو null تفویض کرتے ہیں۔ یہ بات قابل غور ہے کہ کوئی نئی صف نہیں بنائی گئی ہے: System.arraycopy(es, i + 1, es, i, size - 1 - i); وہ حصہ جو مخصوص انڈیکس (i+1) کے تحت پوزیشن کے دائیں طرف ہے ہماری اصل صف (es) میں کاپی کیا جاتا ہے، اور یہ بالکل پوزیشن سے شروع ہو کر واقع ہوتا ہے۔ (i) جہاں عنصر کو حذف کیا جانا تھا۔ اس طرح، ہم نے بائیں طرف شفٹ کیا اور اپنا عنصر مٹا دیا۔
Подробный разбор класса ArrayList [Часть 1] - 9
آئیے ذیل کی صف سے انڈیکس 3 پر عنصر کو ہٹانے کی کوشش کریں:
Подробный разбор класса ArrayList [Часть 1] - 10
آئیے طریقہ کے دوسرے ورژن پر غور کریں:
public boolean remove(Object o)
یہ طریقہ فہرست سے پاس شدہ عنصر کو ہٹا دیتا ہے o، یا زیادہ واضح طور پر، مخصوص لنک پر موجود آبجیکٹ کو۔ اگر کوئی عنصر فہرست میں موجود ہے تو اسے ہٹا دیا جاتا ہے اور تمام عناصر کو بائیں طرف منتقل کر دیا جاتا ہے۔ اگر عنصر فہرست میں موجود ہے اور کامیابی کے ساتھ ہٹا دیا جاتا ہے، تو طریقہ درست ہو جاتا ہے؛ دوسری صورت میں، غلط۔ انڈیکس کے ذریعے حذف کرنے کے آپشن کی طرح، طریقہ کو کہا جاتا ہے fastRemove()، جہاں بالکل وہی اعمال ہوتے ہیں۔ فرق یہ ہے کہ طریقہ آبجیکٹ کلاس کے remove(Object o)طریقہ کار کے ذریعے مطلوبہ آبجیکٹ کو بھی تلاش کرتا ہے ۔ equals()قدر کے لحاظ سے ہٹاتے وقت، لوپ فہرست کے تمام عناصر سے گزرتا ہے جب تک کہ کوئی میچ نہ مل جائے۔ صرف پایا جانے والا پہلا عنصر حذف کیا جائے گا۔ آئیے خلاصہ کریں: متحرک صف سے عناصر کو حذف کرتے وقت، باقاعدہ صف کی طرح کوئی سوراخ باقی نہیں رہتا ہے (حذف شدہ سیل خالی نہیں ہوگا)۔ تمام بعد والے عناصر (جو انڈیکس کے دائیں طرف تھے) کو ایک پوزیشن بائیں طرف منتقل کر دیا گیا ہے۔ فہرست سے عناصر کو مختلف ڈگریوں تک ہٹانے کے لیے کئی اضافی طریقے استعمال کیے جا سکتے ہیں۔ آئیے ان کو مختصراً دیکھتے ہیں۔ ہمارے مجموعہ کو صاف کرنا:
public void clear()
ایک سادہ لوپ forہر ایک عنصر کو null تفویض کرتے ہوئے، صف کے تمام عناصر کے ذریعے اعادہ کرتا ہے۔ آپ ہمارے مجموعے سے ان عناصر کو ہٹا سکتے ہیں جو اس طرح کے دوسرے منتقل کردہ مجموعہ میں موجود ہیں:
public boolean removeAll(Collection< ?> c)
اگر آپ کو متعدد عناصر کو ہٹانے کی ضرورت ہے، تو آپ کو شاید مشروط لوپ میں نہیں کرنا چاہئے: طریقہ استعمال کرنا زیادہ آسان اور محفوظ ہے removeAll()۔ یہ ان عناصر کے مجموعے کو قبول کرتا ہے جنہیں فہرست سے ہٹا دیا جائے گا۔ مجموعہ میں اسی قسم کے عناصر شامل ہونے چاہئیں جو ٹارگٹ لسٹ اسٹور کرتی ہے۔ ورنہ اسے پھینک دیا جائے گا ClassCastException۔ اگر طریقہ کال کے نتیجے میں فہرست کو تبدیل کیا گیا تو طریقہ درست ہو جائے گا۔
Подробный разбор класса ArrayList [Часть 1] - 11
ایسے عناصر کو ہٹاتا ہے جن کا پاس کردہ مجموعہ سے تعلق نہیں ہے:
public boolean retainAll(Collection< ?> c)
Подробный разбор класса ArrayList [Часть 1] - 12
ہم کہتے ہیں کہ ہمارے پاس ایک مجموعہ ہے:
List< String> listFirst = new ArrayList<>();
listFirst.add("White");
listFirst.add("Black");
listFirst.add("Red");
اور دوسرا:
List< String> listSecond = new ArrayList<>();
listSecond.add("Green");
listSecond.add("Red");
listSecond.add("White");
پھر listSecond.retainAll(listFirst)in کے بعد listSecondرہے گا:

"White"
"Red"
چونکہ "سبز" کو ہٹا دیا گیا تھا، جو کہ میں نہیں ہے listFirst۔ لیکن listSecond.removeAll(listFirst)اس کے بعد یہ listSecondباقی رہے گا:

"Green"
Удалorсь все элементы, которые есть в listFirst.
پاس شدہ مجموعہ سے تعلق نہیں ہے - اس کا مطلب ہے کہ اگر ایسے عناصر ہیں جو پاس شدہ مجموعہ میں نہیں ہیں، تو آپ کو انہیں پہلے والے سے ہٹانے کی ضرورت ہے (جس پر طریقہ لاگو ہوتا ہے)۔ منتقل شدہ مجموعہ سے تعلق رکھتا ہے - اس کے مطابق، اگر پہلے اور دوسرے (منتقل شدہ) دونوں مجموعوں میں کوئی عنصر موجود ہو، تو پہلے سے نقل کو ختم کر دیا جاتا ہے۔
protected void removeRange(int fromIndex, int toIndex)
فہرست سے ان تمام عناصر کو ہٹاتا ہے جو شروع ہونے والے مخصوص انڈیکس (شامل) اور اختتامی مخصوص انڈیکس (شامل نہیں) کے درمیان ہیں۔ یہ بات قابل غور ہے کہ طریقہ کو براہ راست ArrayList آبجیکٹ پر نہیں بلایا جا سکتا۔ اسے استعمال کرنے کے لیے آپ کو وراثت میں لینا ہوگا AbstractList/ArrayList۔ طریقہ ایک اور طریقہ کے ذریعہ بھی استعمال کیا جاتا ہے (سب لسٹ، جس پر بعد میں بات کی جائے گی)۔
public boolean removeIf(Predicate< ? super E> filter)
دی گئی پیش گوئی کی بنیاد پر کسی مجموعہ سے عناصر کو ہٹاتا ہے۔ پیشین گوئی بذات خود ایک مخصوص فنکشن/الگورتھم/حالت ہے جس کی بنیاد پر دی گئی حالت کے مطابق ایک یا زیادہ عناصر کو ہٹا دیا جائے گا۔ Predicate- ایک فعال انٹرفیس (صرف ایک طریقہ پر مشتمل ہے، لہذا اسے لیمبڈا کے طور پر استعمال کیا جا سکتا ہے)، اصول پر کام کرتا ہے "ایک پیرامیٹر موصول ہوا - بولین واپس آیا"۔ بنیادی طور پر، یہ طریقہ انٹرفیس سے نفاذ کو اوور رائیڈ کرتا ہے Collectionاور درج ذیل "حکمت عملی" کو لاگو کرتا ہے: یہ عناصر سے گزرتا ہے اور ان کو نشان زد کرتا ہے جو ہمارے Predicate؛ اس کے بعد ان عناصر کو ہٹانے (اور شفٹ) کرنے کے لیے دوسری بار چلایا جاتا ہے جو پہلی تکرار میں نشان زد تھے۔ آئیے ایک انٹرفیس کو لاگو کریں Predicateجو درست ہو جائے گا اگر دو اشیاء برابر ہوں:
class SamplePredicate< T> implements Predicate< T>{
  T varc1;
  public boolean test(T varc){
     if(varc1.equals(varc)){
       return true;
  }
  return false;
  }
}
ایک اور کلاس میں، آئیے اس سے ایک ArrayList بنائیں Stringاور اپنی کلاس کا ایک آبجیکٹ بنائیں جو لاگو کرتا ہے Predicate:
ArrayList< String> color_list = new ArrayList<> ();
SamplePredicate< String> filter = new SamplePredicate<> ();
آئیے متغیر پر varc1ویلیو "وائٹ" لکھتے ہیں:
filter.varc1 = "White";
آئیے فہرست میں چند سطریں شامل کریں:
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
آئیے فہرست میں طریقہ کار پر عمل کریں removeIf، جس میں ہم اپنا اعتراض اس شرط کے ساتھ منتقل کریں گے:
color_list.removeIf(filter);
نتیجے کے طور پر، "سفید" کی قدر والی تمام قطاروں کو فہرست سے ہٹا دیا جائے گا، کیونکہ ہمارا "پیش گوئی" مساوات کے لیے ان کا موازنہ کرتا ہے۔ حتمی فہرست: [سیاہ، سرخ، پیلا]۔
Подробный разбор класса ArrayList [Часть 1] - 13
عناصر کو تبدیل کرنا
public E set(int index, E element)
عنصر کو مخصوص پوزیشن پر indexپاس کردہ سے بدل دیتا ہے element۔ اشاریہ صفر سے بڑا اور آخری عنصر کے اشاریہ سے کم بھی ہونا چاہیے، بصورت دیگر ایک استثناء دیا جائے گا IndexOutOfBoundsException۔ اندرونی صف کی کوئی کاپیاں نہیں ہوتی ہیں۔ بس، مخصوص انڈیکس میں عنصر کے بجائے، ایک نیا عنصر داخل کیا جاتا ہے، یعنی قدر کو اوور رائٹ کریں۔
Подробный разбор класса ArrayList [Часть 1] - 14
public void replaceAll(UnaryOperator<e> operator)
مجموعہ کے تمام عناصر کو تبدیل کرتا ہے (ایک شرط کے ساتھ ممکن ہے)۔ زیادہ تر لیمبڈاس یا گمنام کلاس کے ساتھ مل کر استعمال کیا جاتا ہے (لیکن وضاحت کے لئے، مثال کے طور پر ہم صرف ایک کلاس استعمال کریں گے جو انٹرفیس کو لاگو کرتا ہے) جو انٹرفیس کو لاگو کرتا ہے UnaryOperatorاور اس کے طریقوں کی وضاحت کرتا ہے۔ آئیے انٹرفیس کو لاگو کریں:
class MyOperator< T> implements UnaryOperator< T>{
   T varc1;
   public T apply(T varc){
     return varc1;
  }
}
ایک اور کلاس میں، آئیے اس سے ایک ArrayList بنائیں Stringاور اپنی کلاس کا ایک آبجیکٹ بنائیں جو لاگو کرتا ہے UnaryOperator:
ArrayList< String> color_list = new ArrayList<> ();
MyOperator< String> operator = new MyOperator<> ();
آئیے متغیر پر varc1ویلیو "وائٹ" لکھتے ہیں:
operator.varc1 = "White";
آئیے فہرست میں چند سطریں شامل کریں:
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
آئیے اس فہرست میں ایک طریقہ کار بنائیں replaceAllجس میں ہم اپنا اعتراض منتقل کریں گے operator:
color_list.replaceAll(operator);
نتیجے کے طور پر، فہرست میں موجود تمام اقدار کو "سفید" سے بدل دیا گیا: [سفید، سفید، سفید، سفید، سفید، سفید]۔ اور اس طرح، مثال کے طور پر، آپ مجموعہ میں موجود تاروں سے تمام خالی جگہوں کو ہٹا سکتے ہیں:
ArrayList< String> list = new ArrayList<>(Arrays.asList("A   ", "  B  ", "C"));
list.replaceAll(String::trim);
دیگر طریقے: آپ طریقہ استعمال کرتے ہوئے ArrayList فہرست صف کو باقاعدہ صف میں تبدیل کر سکتے ہیں:
public Object[] toArray()
یا
public < T> T[] toArray(T[] a)
- یہاں واپس کی گئی صف کی قسم کا تعین کیا جاتا ہے runtime یہ طریقہ اجازت دے گا:
  1. کچھ کاموں کو تیز کریں؛
  2. پیرامیٹر کے طور پر ایک ایسے طریقہ پر ایک صف کو منتقل کریں جو براہ راست مجموعہ کو قبول کرنے کے لیے زیادہ بوجھ نہ ہو۔
  3. نئے مجموعہ پر مبنی کوڈ کو میراثی کوڈ کے ساتھ مربوط کرنا جو مجموعوں کو تسلیم نہیں کرتا ہے۔
صف کی ایک کاپی آبجیکٹ واپس کریں:
public Object clone()
براہ کرم نوٹ کریں کہ طریقہ clone()آبجیکٹ کی قسم واپس کرتا ہے، لہذا اسے کال کرنے کے بعد آپ کو مطلوبہ کلاس میں کاسٹ کرنے کی ضرورت ہوگی۔ کلوننگ ایک نئی آزاد شے بناتی ہے۔ کسی چیز کی موجودگی کے لیے مجموعہ چیک کریں:
public boolean contains(Object o)
فہرست میں کسی آبجیکٹ کی موجودگی کی جانچ کرتا ہے (اندرونی طور پر آبجیکٹ کلاس کے مساوی طریقہ استعمال کرتے ہوئے، یعنی حوالہ جات کا موازنہ کرتا ہے)، نتیجہ کے لحاظ سے صحیح/غلط واپس کرتا ہے۔ معمول کے لوپس کے علاوہ، آپ اس کا استعمال کرتے ہوئے ایک مجموعہ (ہر عنصر تک رسائی کے ساتھ ساتھ کچھ کارروائی انجام دینے) کے ذریعے بھی اعادہ کر سکتے ہیں:
public void forEach(Consumer< ? super E> action)
اس طرح ہم اپنی فہرست کو ظاہر کر سکتے ہیں:
List< Integer> numbers = new ArrayList<>(Arrays.asList(10, 20, 50, 100, -5));
numbers.forEach((number)-> System.out.println(number));
لیمبڈاس کا استعمال کیے بغیر آپ کو ایک گمنام کلاس استعمال کرنے اور acceptانٹرفیس کا طریقہ اوور رائڈ کرنے کی ضرورت ہے Consumer۔
numbers.forEach(new Consumer< Integer>() {
  @Override
   public void accept(Integer integer) {
      System.out.println(integer);
          }
});
اس کے انڈیکس کے ذریعہ ایک عنصر حاصل کریں:
public E get(int index)
مجموعہ عناصر تک بے ترتیب رسائی کے لیے استعمال کیا جاتا ہے۔ فہرست میں موجود عنصر کو مخصوص انڈیکس پر لوٹاتا ہے۔ اگر فہرست میں عناصر کی زیادہ سے زیادہ تعداد index < 0ہے یا ہے تو، ایک استثناء دیا جائے گا ۔ یہ فہرست سے کسی عنصر کو بازیافت کرنے کا بنیادی طریقہ ہے، اور اشاریہ کے ذریعہ کسی عنصر کو بازیافت کرنے کا وقت ہمیشہ ایک جیسا رہے گا، قطع نظر اس کے کہ ArrayList کے سائز سے قطع نظر، کیونکہ یہ ایک مخصوص ارے سیل تک رسائی حاصل کر رہا ہے۔ مخصوص اشیاء کے لیے اشاریہ جات تلاش کرنا: index >=IndexOutOfBoundsException
public int indexOf(Object o);
public int lastIndexOf(Object o);
طریقے فہرست میں پہلے (جب دی گئی آبجیکٹ کا پہلی بار سامنا ہوتا ہے) یا آخری واقعہ (جب دی گئی آبجیکٹ کا آخری سامنا ہوتا ہے) عنصر کا انڈیکس لوٹاتا ہے۔ اگر فہرست میں عنصر موجود نہیں ہے، تو طریقے -1 واپس آئیں گے۔
Подробный разбор класса ArrayList [Часть 1] - 16
Подробный разбор класса ArrayList [Часть 1] - 17
عناصر کے لئے مجموعہ چیک کریں:
public boolean isEmpty();
اگر فہرست خالی ہے تو طریقہ درست لوٹتا ہے (دیکھتا ہے کہ فیلڈ برابر ہے یا نہیں size 0)، بصورت دیگر غلط۔ اگر فہرست میں صرف کالعدم عناصر ہیں، تو طریقہ غلط ہو جائے گا۔ دوسرے الفاظ میں، اس طریقہ کار کے ذریعے کالعدم عناصر کو بھی مدنظر رکھا جاتا ہے۔ فہرست میں عناصر کی تعداد معلوم کریں:
public int size();
فہرست میں عناصر کی تعداد (سائز فیلڈ ویلیوز) لوٹاتا ہے۔ عناصر کی تعداد فہرست کی گنجائش (صلاحیت) سے مختلف ہو سکتی ہے۔ فہرست کے لیے ایک تکرار کرنے والا حاصل کریں:
public Iterator< E> iterator();
لوپ یا کسی اور پروسیسنگ میں بعد میں استعمال کے لیے فہرست کے لیے ایک تکرار کرنے والا لوٹاتا ہے۔ تکرار کرنے والا فیل فاسٹ رویے کو نافذ کرتا ہے۔ اگر یہ مجموعہ کے ذریعے چلتا ہے اور اس میں کچھ ترمیمات کو نوٹس کرتا ہے (جو کہ تکرار کرنے والے طریقوں سے حاصل نہیں کیا گیا تھا)، تو یہ فوری طور پر ایک استثناء پھینک دیتا ہے ConcurrentModificationException۔ تکرار کرنے والے کو کچھ کہا جاتا ہے modification count۔ جب تکرار کنندہ ہر ایک کے بعد مجموعہ کے ذریعے تکرار کرتا ہے next/hasNext/remove، تو یہ اس کاؤنٹر کو چیک کرتا ہے۔ اگر یہ اس سے مماثل نہیں ہے جس کی تکرار کرنے والے نے توقع کی تھی تو یہ ایک استثناء پھینک دیتا ہے۔ میں یہاں تکرار کرنے والوں پر تفصیل سے غور نہیں کروں گا۔
public ListIterator< E> listIterator() и public ListIterator< E> listIterator(int index)
لوپ یا کسی اور پروسیسنگ میں بعد میں استعمال کے لیے فہرست کے لیے ایک فہرست تکرار کرنے والا لوٹاتا ہے۔ انٹرفیس فہرست کے دو طرفہ ٹراورسل اور اس کے عناصر میں ترمیم کے لیے ListIteratorانٹرفیس کو بڑھاتا ہے ۔ Iteratorاوورلوڈ ورژن میں، آپ انڈیکس کو پاس کر سکتے ہیں جہاں سے "ٹراورسل" شروع ہوگا۔ اس معاملے میں انڈیکس پہلے عنصر کی نشاندہی کرتا ہے جہاں سے طریقہ اپنا کام شروع کرے گا next()، اور جب طریقہ کو بلایا جائے گا، تو previous()ٹراورسل انڈیکس "پاسڈ انڈیکس - 1" کے تحت عنصر سے شروع ہوگا۔
public Spliterator <E> spliterator()
جاوا 8 نے ایک نئی قسم کا لیٹ بائنڈنگ اور فیل فاسٹ ایٹریٹر متعارف کرایا ہے جسے ڈیلیمیٹر ایٹریٹر کہتے ہیں۔ الگ کرنے والے تکرار کرنے والے آپ کو عناصر کی ترتیب پر تکرار کرنے کی اجازت دیتے ہیں، لیکن وہ مختلف طریقے سے استعمال ہوتے ہیں۔ Spliterator انٹرفیس کی سب سے اہم خصوصیت عناصر کی ترتیب کے انفرادی حصوں کے متوازی تکرار کو سپورٹ کرنے کی صلاحیت ہے، اور اسی لیے متوازی پروگرامنگ۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION