در قسمت هفتم آموزش جاوا با آرایهها و انواع آن آشنا خواهیم شد.
آرایهها (Arrays)
فرض کنید قرار است نمرات ۲۰ دانشجو را در حافظه نگهداری کنید. آیا باید ۲۰ متغیر مثلا از نوع double تعریف کنید یا روشی بهتر برای این کار وجود دارد؟ اینجاست که آرایهها وارد عمل میشوند.
آرایه را میتوان تعدادی خانه کنار هم در حافظه رم در نظر گرفت که میتوان با داشتن شماره هر خانه (اندیس آن) به محتویات آن خانه دسترسی پیدا کرد.
برای تعریف یک آرایه در جاوا همانند تعریف یک متغیر عمل میکنیم: باید یک نام برای آرایه خود انتخاب کنیم (قوانین نامگذاری آرایه مانند قوانین نامگذاری متغیرهاست) سپس باید نوع دادهای که آرایه ما قرار است در خانههای خود نگهداری کند را مشخص کنیم.
چند نکته مهم راجع به آرایهها
۱- تمام خانههای یک آرایه فقط میتوانند نوع دادهای که برای کل آرایه تعریف شده است را نگه دارند و در یک آرایه نمیشود مثلا یک خانه دادهای از جنس int و خانه دیگر دادهای از جنس double داشته باشد.
۲- اندیسگذاری خانههای یک آرایه از ۰ شروع میشود نه از ۱٫
۳- وقتی یک آرایه با تعداد خانه مشخص تعریف کردیم دیگر در زمان اجرای برنامه نمیتوانیم اندازه (تعداد خانهها) آرایه را کم یا زیاد کنیم. (بزرگترین عیب آرایهها هم همین است.)
به شکل زیر توجه کنید:
در این شکل آرایهای به نام myArray داریم که ۶ خانه دارد و درون هر کدام از این خانهها یک مقدار عددی قرار گرفته است (اعداد بنفش). همچنین اندیس هر خانه آرایه (شماره آن خانه) در زیر آن با رنگ قرمز نوشته شده است. همانطور که گفتیم شمارهگذاری خانههای آرایه از ۰ شروع میشود نه از ۱٫
شکل کلی تعریف یک آرایه در جاوا به صورت زیر است:
نام آرایه نوع داده آرایه[] = new تعداد خانههای آرایه] نوع داده آرایه];
با دستور new در قسمت شیگرایی به طور کامل آشنا خواهید شد.
آرایهای که در شکل قبل دیدیم به صورت زیر تعریف میشود:
int myArray[] = new int[6];
نوع داده آرایه ما int و نام آن myArray است و ۶ خانه دارد. ما فقط آرایه را تعریف کردیم و به آن مقدار ندادیم بنابراین مقدار پیشفرضی که در خانههای آرایه وجود دارد ۰ است (چون نوع داده آن عددی است) حالا برای مقدار دادن به هر کدام از خانههای آرایه مانند مقدار دادن به یک متغیر عمل میکنیم اما با یک تفاوت کوچک:
;مقدار مورد نظر = [اندیس خانه]نام آرایه
منظور از اندیس خانه همان شماره خانهای از آرایه است که میخواهیم مقداری را درون آن قرار دهیم.
در کد زیر میخواهیم در خانه دوم آرایهای که تعریف کردیم مقدار ۱۳ را قرار دهیم:
public class Main { public static void main(String[] args) { int myArray[] = new int[6]; myArray[1] = 13; } }
همانطور که گفتیم چون اندیسگذاری خانههای آرایه از ۰ شروع میشود بنابراین اندیس خانه دوم ۱ است.
حالا اگر بخواهیم به یکی از خانههای آرایه دسترسی پیدا کنیم باید به صورت زیر عمل کنیم:
[شماره اندیس]نام آرایه
در کد زیر که ادامه کدهای قبل است یک متغیر تعریف کردیم و مقدار خانه دوم آرایه خود را درون آن متغیر قرار دادیم سپس با دستور چاپ، مقدار خانه دوم آرایه را چاپ کردیم:
public class Main { public static void main(String[] args) { int myArray[] = new int[6]; myArray[1] = 13; int myNumber = myArray[1]; System.out.println(myArray[1]); } }
اما روش دیگری نیز برای تعریف یک آرایه وجود دارد. اگر بخواهیم در همان ابتدای تعریف آرایه به آن مقدار بدهیم میتوانیم به صورت زیر عمل کنیم:
public class Main { public static void main(String[] args) { double[] numbers = {1, 5, 12.5, 8.75, 6}; System.out.println(numbers.length); } }
در این روش به هر تعداد که مقدار وارد کنید تعداد خانههای آرایه هم همان قدر میشود.
در این کد آرایه ای را از جنس double تعریف کردیم و ۵ مقدار به آن دادیم. پس حالا این آرایه ۵ خانه دارد. در خط بعدی طول آرایه (تعداد خانههای آن) را چاپ کردیم. به صورت زیر میتوان طول آرایه را خواند:
نام آرایه.length
پیمایش یک آرایه (Array Iteration)
گاهی اوقات لازم است تا خانههای یک آرایه را از اول تا آخر پیمایش کنیم. این کار را میتوان با استفاده از حلقههای تکرار انجام داد.
مثال: در برنامه زیر آرایهای از نمرات دانشجویان یک کلاس داریم. میخواهیم میانگین نمرات را حساب کنیم:
public class Main { public static void main(String[] args) { double[] nomarat = {8, 5, 12.5, 8.75, 6, 20, 19.5, 16}; int sum = 0; for (int i = 0; i < nomarat.length; i++) { sum += nomarat[i]; } System.out.println(sum / nomarat.length); } }
متغیری به نام sum تعریف کردیم. در حلقه تکرار مجموع تمام نمرات را به دست آوردیم. سپس در آخر با تقسیم مجموع نمرات بر تعداد نمرات، میانگین کل نمرات را چاپ میکنیم. توجه کنید که شرط حلقه i < nomarat.length است چون nomarat.length به ما مقدار ۸ را میدهد که تعداد خانههای آرایه است اما چون اندیسهای آرایه از ۰ شروع میشود بنابراین اندیس آخرین خانه آرایه ۷ است پس i باید تا ۷ افزایش پیدا کند.
روش دیگر پیمایش آرایه استفاده از یک نوع حلقه for به نام for each میباشد. این حلقه از اولین خانه آرایه شروع کرده و تا آخر پیش میرود. در این نوع حلقه یک متغیر تعریف میشود که مقدار هر خانه آرایه را در هر دور حلقه در خود نگه میدارد. شکل کلی آن به صورت زیر است:
for (نام آرایه : نام متغیر نوع داده آرایه) {
}
مثال:
public class Main { public static void main(String[] args) { int[] numbers = {1, 2, 5, 7, 8, 9}; for (int num : numbers) { System.out.println(num); } }
این حلقه تمام مقادیری که در این آرایه قرار گرفتهاند را چاپ میکند به این صورت که حلقه از اولین خانه آرایه شروع میکند و مقدار آن را درون متغیر num که تعریف کردیم قرار میدهد و ما در بدنه حلقه میتوانیم از متغیر num برای دسترسی به خانه فعلی آرایه استفاده کنیم و به همین ترتیب تا آخر پیش میرود.
نکته: تفاوت استفاده از for each با حلقه for معمولی این است که در حلقه معمولی علاوه بر خواندن خانههای آرایه می توان مقدار آنها را تغییر هم داد اما در for each فقط میتوانیم خانههای آرایه را بخوانیم و نمیتوانیم مقادیر آنها را تغییر دهیم.
مثال: در برنامه زیر مقدار تمام خانههای آرایه را به ۵ تغییر میدهیم:
public class Main { public static void main(String[] args) { int[] numbers = {1, 2, 5, 7, 8, 9}; for (int i = 0; i < numbers.length; i++) { numbers[i] = 5; } } }
آرایههای دو بعدی (Two Dimensional Arrays)
آرایههای دو بعدی را میتوان به یک جدول که شامل چند سطر و ستون است تشبیه کرد. شکل کلی تعریف یک آرایه دو بعدی به صورت زیر است:
نام آرایه نوع داده آرایه[][] = new تعداد ستونها][تعداد سطرها]نوع داده آرایه];
به شکل زیر دقت کنید:
آرایهای دو بعدی از جنس int به نام myArray را در شکل میبینید. این آرایه ۳ سطر و ۴ ستون دارد پس به صورت زیر تعریف میشود:
int myArray[][] = new int[3][4];
همانطور که در شکل مشخص است برای دسترسی به محتوای خانه سوم از سطر دوم به صورت زیر عمل کردیم:
myArray[1][2]
برای مقداردهی به یکی از خانههای آرایه نیز میتوان مانند آرایههای یک بعدی عمل کرد. مثلا اگر بخواهیم به خانهای که در سطر آخر و ستون سوم آرایه myArray قرار دارد مقدار ۱۳ را بدهیم به شکل زیر عمل میکنیم:
myArray[2][2] = 13;
روش دیگر مقداردهی به آرایههای دو بعدی، مقداردهی در زمان تعریف آرایه است. فرض کنید میخواهیم آرایهای از جنس int با ۳ سطر و ۲ ستون با مقادیر اولیه تعریف کنیم:
public class Main { public static void main(String[] args) { int[][] numbers = {{1, 4}, {6, 7}, {4, 8}}; } }
همانطور که میبینید برای هر سطر یک جفت آکولاد نوشتیم که درون هر سطر دو مقدار وجود دارد که یعنی این آرایه یک آرایه دو بعدی ۳×۲ است.
پیمایش آرایههای دو بعدی
برای پیمایش آرایههای دو بعدی بهترین راه استفاده از دو حلقه for تو در تو است. حلقه بیرونی مسئول پیمایش سطرها و حلقه درونی مسئول پیمایش ستونهای آرایه خواهد بود.
مثال:
public class Main { public static void main(String[] args) { int[][] numbers = {{1, 4}, {6, 7}, {4, 8}}; for (int i = 0; i < numbers.length; i++) { for (int j = 0; j < numbers[i].length; j++) { System.out.print(numbers[i][j]); } System.out.println(); } } }
در این کد numbers.length تعداد سطرهای آرایه را به ما میدهد.
i به عنوان شماره سطر و j به عنوان شماره ستون استفاده میشود.
در حلقه for دوم برای به دست آوردن تعداد ستونها از numbers[i].length استفاده کردیم.
آرایههای بی قاعده (Irregular Arrays)
به این نوع آرایهها دندانه دار (Jagged) نیز میگویند. آرایههای بی قاعده آرایههایی هستند که تعداد ستونهای آن در هر سطر میتواند متفاوت باشد.
مثال:
public class Main { public static void main(String[] args) { int[][] numbers = new int[3][]; numbers[0] = new int[2]; numbers[1] = new int[5]; numbers[2] = new int[4]; } }
هنگام تعریف آرایه فقط تعداد سطرهای آن را مشخص کردیم و سپس برای هر سطر تعداد ستونهای آن را به شکلی که میبینید تعریف کردیم. شکل این آرایه را میتوان به صورت زیر رسم کرد:
نکته: پیمایش این آرایهها مانند آرایههای دو بعدی معمولی است.
آرایههای سه بعدی
آرایههای سه بعدی را میتوان آرایهای از آرایههای دو بعدی در نظر گرفت:
این شکل یک آرایه سه بعدی را نشان میدهد. همانطور که میبینید در هر خانه این آرایه یک آرایه دو بعدی وجود دارد. این آرایه را به صورت زیر تعریف میکنیم:
int[][][] numbers = new int[2][3][15];
همچنین برای دسترسی به خانه مورد نظر هم مانند قبل عمل میکنیم. (با مشخص کردن همه ابعاد)
نکته: پیمایش این آرایهها مشابه پیمایش آرایههای دو بعدی است با این تفاوت که باید از سه حلقه تو در تو استفاده کرد.
نکته: پرکاربردترین نوع آرایهها که در برنامهنویسی روزمره استفاده میشود آرایههای یک بعدی و دوبعدی هستند و از آرایههای بیقاعده و سه بعدی به ندرت استفاده میشود.
قسمت هفتم بسیار خوب بود و آرایه ها جزو بهترین قسمت های برنامه نویسی به شمار میروند.
توی حلقه for each هم تست کردم ومیشه مقادیررو تغییربدیم که!!! چجوریه؟
int[] numbers = {1, 2, 5, 7, 8, 9};
for (int num : numbers) {
num = 25;
System.out.println(num);
}
با سلام
درسته که مقدار num رو تغییر دادید اما num فقط یه متغیر موقت برای نگهداری خونه های آرایه است یعنی در واقع در هر بار اجرای حلقه مقدار یکی از خونه های آرایه توی این متغیر num کپی میشن و اگر مقدار num رو تغییر بدید فقط مقدار اون متغیر موقت رو تغییر دادید.
کافیه بعد از اینکه حلقه تون تموم شد با یه دستور چاپ مقدار یکی از خونه های آرایه رو چاپ کنید و ببینید که تغییری نکرده.
آها. دقیقا همینطوره که میگید.
مرررررررسی.
آیا میشه تعداد خانه های یک آرایه رو یک متغیر مثل a گذاشت و ایم تغیر رو هنگام اجرای برنامه از طریق ورودی برنامه از کابر گرفت ؟؟؟
بله. تعداد خانه های آرایه باید مقداری از نوع int باشد و شما می توانید به اشکال مختلف یک عدد صحیح بگیرید و به عنوان تعداد خانه های آرایه استفاده کنید منتها باید توجه داشته باشید که اندازه آرایه را بعد از تعریف آن نمی توان تغییر داد و باید بعد از اینکه تعداد خانه های آرایه را از کاربر گرفتید اقدام به تعریف آرایه کنید.
با سلام وخسته نباشید خدمت استاد محترم
بنده برنامه نویسی جاوا رو تازه شروع کردم یه سوالی که داشتم برای تایپ نام کلاس که با حروف بزرگ شروع میشن تنظیمات خاصی وجود نداره که از دکمه caps lock استفاده نکنیم . چون یه خرده آزار دهنده هستش که مدام caps lock روشن خاموش بشه ؟
ممنون بابت تمام زحمتایی که میکشین
خب پس دکمه Shift رو کیبورد چیکار میکنه؟!
البته بنده از NeatBeans استفاده میکنم
با سلام
در پاراگراف سوم این بخش از اموزش توضیح دادید که برای تعریف یک آرایه باید ابتدا یک نام برای آرایه انتخاب کرد و سپس نوع آرایه رو مشخص کرد. که این روند کاملا اشتباه و باید به صورت بر عکس باشد همانطور که خودتون در ادامه توضیح دادید .
ممنون از آموزش خوبتون
با سلام شما فرمودید که داخل حلقه for each نمیشه مقدار یک arry رو تعغیر داد. ولی توی این قطعه کد زیر بنده این کار رو با مدرک انجام دادم.
public static void main(String[] args) {
int[] numbers = {1, 5, 8, 9, 6};
System.out.println(“First for each”);
for (int num : numbers) {
System.out.println(num);
}
System.out.println(“********************”);
System.out.println(“secound for each to change arry ‘numbers'”);
for (int num : numbers) {
numbers[numbers.length – 1] = 10;
System.out.println(num);
}
System.out.println(“********************”);
System.out.println(“last column of arry ‘numbers’ is changed!”);
System.out.println(numbers[numbers.length – 1]);
}
اگه بنده اشتباه متوجه شده لطفا روشن بفرمایید بنده رو ولی اگه شما اشتباه کردید لطفا متن اصلاح بشود. ممنون از آموزش مفیدتون.
ای خط کدی که شما در بخش دوم اضافه کردید یعنی
numbers[numbers.length – ۱] = ۱۰;
در هر جایی از کد باشه محتویات آرایه را تغییر میدهد.منظور از عدم تغییر در for each اینکه که اگر مقدار آرگومان اول for ،یعنی مثلا در مثال شما متغیر num را تغییر بدهید ، مقادیر در آرایه اصلی هیچ تغییری نمیکند.
سوال بنده
اگر بخواهیم به طور دلخواه یک لیست با طول نا معلوم درست کنیم و اعداد را کاربر با کیبرد بدهد و در خانمه با عدد مثلا صفر خاتمه یابد . چطور میتوان این اری را یجاد کرد؟