سلام! در درسهای قبلی، به بررسی عمیق آرایهها پرداختیم و نمونههای رایج کار با آرایهها را مرور کردیم. در این درس، مروری دقیقتر در Java ArrayList خواهیم داشت. به طور کلی، آرایه ها بسیار مفید هستند. و همانطور که قبلاً متوجه شده اید، می توانید کارهای زیادی با آنها انجام دهید :) اما آرایه ها دارای تعدادی کاستی هستند.
- اندازه محدود شما باید بدانید که آرایه شما در زمان ایجاد چند عنصر باید داشته باشد. اگر دست کم بگیرید، فضای کافی نخواهید داشت. بیش از حد برآورد کنید، و آرایه نیمه خالی می ماند، که این نیز بد است. پس از همه، شما هنوز هم بیشتر از آنچه لازم است حافظه اختصاص می دهید.
- یک آرایه روشی برای افزودن عناصر ندارد. شما همیشه باید به صراحت نمایه موقعیتی را که می خواهید عنصری را در آن اضافه کنید مشخص کنید. اگر به طور تصادفی شاخصی را برای موقعیتی که توسط مقداری که نیاز دارید مشخص کنید، بازنویسی می شود.
- هیچ روشی برای حذف یک مورد وجود ندارد. یک مقدار را فقط می توان "صفر کرد".
public class Cat {
private String name;
public Cat(String name) {
this.name = name;
}
public static void main(String[] args) {
Cat[] cats = new Cat[3];
cats[0] = new Cat("Thomas");
cats[1] = new Cat("Behemoth");
cats[2] = new Cat("Lionel Messi");
cats[1] = null;
System.out.println(Arrays.toString(cats));
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
خروجی: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] خوشبختانه، سازندگان جاوا به خوبی از مزایا و معایب آرایه ها آگاه هستند و بنابراین ساختار داده ای بسیار جالبی به نام Java ArrayList ایجاد کردند . به ساده ترین شکل ممکن، جاوا ArrayList یک آرایه "سوپ شده" با بسیاری از ویژگی های جدید است.
چگونه یک ArrayList ایجاد کنیم
ایجاد آن بسیار آسان است:ArrayList<Cat> cats = new ArrayList<Cat>();
اکنون لیستی برای ذخیره اشیاء Cat ایجاد کرده ایم. توجه داشته باشید که اندازه ArrayList را مشخص نمی کنیم ، زیرا می تواند به طور خودکار گسترش یابد. چه طور ممکنه؟ در واقع بسیار ساده است. ممکن است شما را شگفت زده کند، اما ArrayList در جاوا بر روی یک آرایه بسیار معمولی ساخته شده است :) بله، حاوی یک آرایه است و عناصر ما در آنجا ذخیره می شوند. اما ArrayList در جاوا روش خاصی برای کار با آن آرایه دارد:
- هنگامی که آرایه داخلی پر می شود، ArrayList یک آرایه جدید در داخل ایجاد می کند. اندازه آرایه جدید به اندازه آرایه قدیمی ضربدر 1.5 به اضافه 1 است.
- تمام داده ها از آرایه قدیمی به آرایه جدید کپی می شوند
- آرایه قدیمی توسط زباله جمع کن تمیز می شود.
add()
روش است
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<Cat>();
cats.add(new Cat("Behemoth"));
}
موارد جدید به انتهای لیست اضافه می شود. اکنون هیچ خطری برای سرریز کردن آرایه وجود ندارد، بنابراین این روش کاملاً ایمن است. به هر حال، ArrayList نه تنها می تواند یک شی را با شاخص آن پیدا کند، بلکه برعکس: می تواند از یک مرجع برای یافتن شاخص یک شی در ArrayList استفاده کند ! این همان چیزی است که متد indexOf() برای آن است: ما یک مرجع را به شی مورد نظر خود ارسال می کنیم و indexOf() شاخص آن را برمی گرداند:
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
cats.add(lionel);
cats.add(fluffy);
int thomasIndex = cats.indexOf(thomas);
System.out.println(thomasIndex);
}
خروجی: 0 درست است. شی thomas ما در واقع در عنصر 0 ذخیره می شود. آرایه ها فقط اشکالاتی ندارند. آنها همچنین مزایای غیرقابل انکاری دارند. یکی از آنها امکان جستجوی عناصر بر اساس فهرست است. از آنجایی که ما به یک شاخص اشاره می کنیم، یعنی به یک آدرس حافظه خاص، جستجو در یک آرایه به این روش بسیار سریع است. ArrayList
می داند چگونه آن را انجام دهد، بیش از حد! متد get() این را پیاده سازی می کند:
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
cats.add(lionel);
cats.add(fluffy);
Cat secondCat = cats.get(1);
System.out.println(secondCat);
}
خروجی: Cat{name='Behemoth'} علاوه بر این، میتوانید به راحتی متوجه شوید که آیا ArrayList دارای یک شی خاص است یا خیر. این کار با استفاده از روش ArrayList contain() انجام میشود :
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
cats.add(lionel);
cats.add(fluffy);
cats.remove(fluffy);
System.out.println(cats.contains(fluffy));
}
این روش بررسی می کند که آیا آرایه داخلی ArrayList حاوی عنصر است یا خیر، و یک بولی (درست یا نادرست) برمی گرداند. خروجی: false و نکته مهم دیگر در مورد درج. ArrayList به شما امکان می دهد از یک شاخص برای درج عناصر نه تنها در انتهای آرایه، بلکه در هر جایی استفاده کنید. برای این کار دو روش دارد:
- افزودن ArrayList (شاخص int، عنصر Cat)
- مجموعه ArrayList (شاخص int، عنصر Cat)
در اینجا یک مثال است:
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
System.out.println(cats.toString());
cats.set(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using set
System.out.println(cats.toString());
}
خروجی: [[Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Behemoth'}] ما فهرستی از ۲ گربه داشتیم . سپس یک عنصر دیگر را با استفاده از متد set() به عنوان عنصر 0 درج کردیم . در نتیجه، عنصر قدیمی با عنصر جدید جایگزین شده است.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
System.out.println(cats.toString());
cats.add(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using add
System.out.println(cats.toString());
}
و در اینجا می بینیم که add() متفاوت عمل می کند. همه عناصر را به سمت راست حرکت می دهد و سپس مقدار جدید را به عنوان عنصر 0 می نویسد. خروجی: [Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Thomas'}, Cat{name='Behemoth'}] برای پاک کردن کامل لیست، از متد clear() استفاده میکنیم :
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
cats.add(lionel);
cats.add(fluffy);
cats.clear();
System.out.println(cats.toString());
}
خروجی: [] همه چیز از لیست حذف شد. به هر حال، لطفاً توجه داشته باشید: برخلاف آرایهها، ArrayList متد toString() را لغو میکند و لیست را بهطور مناسب بهعنوان رشته نمایش میدهد. با آرایه های معمولی، باید از کلاس Arrays برای این کار استفاده می کردیم. و از آنجایی که به Arrays اشاره کردم : جاوا به شما امکان می دهد به راحتی بین یک آرایه و یک ArrayList "سوئیچ" کنید ، یعنی یکی را به دیگری تبدیل کنید. کلاس Arrays یک متد Arrays.asList() برای این کار دارد . ما از آن برای دریافت محتویات به عنوان یک آرایه و ارسال آنها به سازنده ArrayList استفاده می کنیم :
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
Cat[] catsArray = {thomas, behemoth, lionel, fluffy};
ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
System.out.println(catsList);
}
خروجی: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}] همچنین می توانید در جهت مخالف بروید: دریافت کنید یک آرایه از یک شی ArrayList . ما این کار را با استفاده از متد toArray() انجام می دهیم :
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
cats.add(lionel);
cats.add(fluffy);
Cat[] catsArray = cats.toArray(new Cat[0]);
System.out.println(Arrays.toString(catsArray));
}
نکته: یک آرایه خالی را به متد toArray() ارسال کردیم . این یک خطا نیست. در داخل کلاس ArrayList این متد به گونه ای پیاده سازی می شود که عبور از یک آرایه خالی باعث افزایش کارایی آن می شود. فقط این را برای آینده در نظر داشته باشید (البته، می توانید یک آرایه با اندازه خاص را ارسال کنید؛ این نیز کار می کند). اوه، در مورد اندازه. اندازه فعلی لیست را می توان با استفاده از روش size() پیدا کرد :
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
cats.add(lionel);
cats.add(fluffy);
System.out.println(cats.size());
}
درک این نکته مهم است که برخلاف ویژگی طول آرایه ، متد ArrayList.size() تعداد واقعی عناصر را برمیگرداند، نه ظرفیت اصلی را. از این گذشته، هنگام ایجاد ArrayList اندازه ای را مشخص نکردیم . با این حال، می توانید آن را مشخص کنید - ArrayList سازنده مناسبی دارد. اما از نظر افزودن عناصر جدید، این رفتار آن را تغییر نمی دهد:
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>(2);// create an ArrayList with an initial capacity of 2
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Behemoth");
Cat lionel = new Cat("Lionel Messi");
Cat fluffy = new Cat ("Fluffy");
cats.add(thomas);
cats.add(behemoth);
cats.add(lionel);
cats.add(fluffy);
System.out.println(cats.size());
}
خروجی کنسول: 4 ما فهرستی از 2 عنصر ایجاد کردهایم، اما وقتی به آن نیاز داشتیم، بیصدا گسترش مییابد. ملاحظات دیگر این است که اگر در ابتدا یک لیست بسیار کوچک ایجاد کنیم، باید بیشتر گسترش یابد که از برخی منابع استفاده می کند. ما در این درس به سختی به روند حذف عناصر از ArrayList اشاره کردیم البته، این به این دلیل نیست که ذهن ما را از دست داده است. ما این موضوع را در یک درس جداگانه قرار داده ایم که بعداً با آن آشنا خواهید شد :) برای تقویت آنچه آموخته اید، پیشنهاد می کنیم یک درس ویدیویی از دوره جاوا ما تماشا کنید.
GO TO FULL VERSION