บทที่ 62. Array คือ โครงสร้างข้อมูลชนิดหนึ่ง ที่ใช้เก็บข้อมูลชนิดเดียวกัน โดยก่อนที่เราจะใช้
Array เก็บข้อมูลได้ เราต้องประกาศ Array และ จองเนื้อที่ในหน่วยความจาก่อน
1. การประกาศ Array นั้นคล้ายกับการประกาศตัวแปรมาก เพียงแต่เติมวงเล็บก้ามปู
เข้าไปดังนี้:ชนิดของข้อมูล [ ] ชื่อ_Array;
2. การจองเนื้อที่ในหน่วยความจา สามารถทาได้โดยใช้ syntax ดังนี้:-
ชื่อ_Array = new ชนิดของข้อมูล [ขนาดของ Array];
ตัวอย่าง การประกาศ Array ชื่อ myList เพื่อเก็บค่าทศนิยม 10 ค่า (ดัง
แสดงดังตัวอย่างด้านล่าง):double [] myList; // ประกาศ Array ชื่อ
myList
myList = new double[10]; // จองเนื้อที่ในหน่วยความจาสาหรับ
เก็บทศนิยม 10 ค่าให้ myListตัวอย่างข้างต้นสามารถถูกเขียนให้อยู่ในบรรทัดเดียวได้
ดังนี้:-
double [] myList = new double[10];ข้อสังเกต เวลาจอง
เนื้อที่ในหน่วยความจาให้ myList เราต้องระบุว่า เราจะจองเพื่อเก็บข้อมูลชนิด
3. double ซึ่งเป็นชนิดข้อมูลเดียวกับที่เราประกาศ myList
จากรูป Array ชื่อ myList จะมีหน่วยความจาให้ใช้เก็บค่าทศนิยม 10 ค่า
โดย myList[0] จะเป็นสมาชิก
ของ Array หมายเลข 0 (ซึ่งคือสมาชิกแรกของ myList) และ
myList[9] จะเป็นสมาชิกของ Array หมายเลข 9 (ซึ่งคือสมาชิกตัวสุดท้ายของ
myList)
เกร็ดความรู้1: หลังจากสร้าง Array แล้ว ขนาดของ Array จะคงที่ ซึ่ง
ขนาดของ Array จะถูกเก็บในตัวแปรตัว
หนึ่งของ Array (เรียกตัวแปรนี้ว่า field ของ Array) ที่ชื่อว่า
length ดังนั้น myList.length ในตัวอย่างข้างต้นจะ
เก็บค่า 10 ไว้(นิสิตควรจาตัวแปรตัวนี้ไว้ เพราะมีประโยชน์ในการกาหนด
เงื่อนไขของ loop ที่จะมาดาเนินการกับArray)
เกร็ดความรู้ 2: เมื่อ Array ถูกสร้างขึ้นมา โดยโปรแกรมเมอร์ไม่ได้
กาหนดค่าเริ่มต้นให้สมาชิกใน Array Java จะ
4. กาหนดค่าเริ่มต้นให้ทุกสมาชิกใน Array อัตโนมัติ ตามชนิดของข้อมูลใน Array ตามรายละเอียด
ต่อไปนี้:-
- ถ้าชนิดของข้อมูลใน Array เป็นตัวเลข ค่าของทุกสมาชิกถูกกาหนดให้เป็น 0 หมด
- ถ้าชนิดของข้อมูลใน Array เป็น char ค่าของทุกสมาชิกถูกกาหนดให้เป็น null
character ('u0000') หมด
- ถ้าชนิดของข้อมูลใน Array เป็นตรรกะบูล ค่าของทุกสมาชิกถูกกาหนดให้เป็น
false หมด
double[] myList = new double[10];
myList อ้างอิง
myList[0]
myList[1]
myList[2]
myList[3]
myList[4]
myList[5]
myList[6]
myList[7]
myList[8]
myList[9]
5. ชื่อ Array (หรือ ตัวแปรอ้างอิงไปยังโครงสร้างข้อมูล)สมาชิกของ Array หมายเลข
5การเข้าถึงสมาชิกใน Array
myList เป็นตัวแปรที่ชี้ไปยังหน่วยเก็บความจาของ Array เท่านั้น ถ้า
เราจะไปอ่านหรือกาหนดค่าให้กับสมาชิกในตาแหน่งต่าง ๆ ของ Array เราต้องระบุ
ตาแหน่งในวงเล็บก้ามปูให้แน่นอน เช่น ถ้าเราต้องการนาค่า 10.0 ไปใส่ในสมาชิก
ตาแหน่งที่ 5 ของ Array เราต้องเขียน code ดังนี้:-
myList[5] = 10.0; // กาหนดให้สมาชิกในตาแหน่งที่ 5 ของ
myList มีค่าเท่ากับ 10.0 ให้นิสิตใช้ตัวแปรของ Array ที่มีหมายเลขตาแหน่ง
กากับเสมือนนิสิตใช้ตัวแปรตัวหนึ่ง นั่นคือ ใช้ได้ทั้งอ่านและเก็บค่าลงไป (เรียกตัวแปร
ประเภทนี้ว่าตัวแปรที่ถูกชี้ หรือ Indexed Variable)
ข้อควรระวัง: ถ้า Array มีขนาดเท่ากับ N (มีสมาชิก N ตัว) ตาแหน่งของสมาชิกจะ
เริ่มที่ตาแหน่ง 0 และสิ้นสุดที่ตาแหน่งที่ N-1 เสมอ เมื่อเราระบุตาแหน่งเกินขอบเขตของ
Array เช่น myList[10] = 10.0 Java จะแจ้ง
6. ข้อผิดพลาด ArrayIndexOutofBound (แปลว่า ค่าตาแหน่งของ Array
เกินขอบเขต) เพราะ myList มีตาแหน่ง
ของสมาชิกสูงสุดที่ 9 (ขนาดของ myList – 1 เท่ากับ 9)การกาหนดค่าตั้งต้นให้
สมาชิกใน Arrayเราสามารถกาหนดค่าเริ่มต้นให้สมาชิกใน Array หลังจากเราสร้าง
Array แล้ว ดังตัวอย่างต่อไปนี้
double[] myList = new double[4];
myList[0] = 1.9;
myList[1] = 2.9;
myList[2] = 3.4;
myList[3] = 3.5;
เราสามารถเขียน 5 บรรทัดข้างต้นในรูปแบบย่อได้ดังนี้:-
double[] myList = {1.9, 2.9, 3.4, 3.5};
7. Java บังคับให้เรากาหนดค่าเริ่มต้นให้สมาชิกใน Array ในบรรทัดเดียวเท่านั้น เราไม่
สามารถมากาหนดค่า
เริ่มต้นทีหลังแบบตัวอย่างด้านล่างได้
double[] myList;
myList = {1.9, 2.9, 3.4, 3.5};ตัวอย่างที่ 1: พิมพ์ค่าของสมาชิกทุกตัวใน
Array
for(int i = 0; i < myList.length; i++) {
System.out.println( myList[i] ); // พิมพ์ค่าสมาชิกตาแหน่งที่ i ของ
myList
}
8. ตัวอย่างที่ 2: การก กาหนดค่าเริ่มต้นใน Array
ตัวอย่างนี้จะกาหนดค่าเริ่มต้นให้ทุกสมาชิกของ Array โดยจะกาหนดให้สมาชิก
ตาแหน่งที่ i มีค่าเท่ากับ
10 * i ดังนี้:-
for(int i = 0; i < myList.length; i++) {
myList[i] = 10 * i;
}
ตัวอย่างที่ 3: หาค่าผลบวกของค่าของทุก ๆ สมาชิกใน Array
int sum = 0;
for(int i = 0; i < myList.length; i++) {
sum += myList[i];
}
System.out.println( sum );
9. ตัวอย่างที่ 4: หาค่าที่มากที่สุดใน Array
int max = Integer.MIN_VALUE;
for(int i = 0; i < myList.length; i++) {
if( myList[i] > max)
max = myList[i];
}
System.out.println( max );
10. ตัวอย่างที่ 5: หาตาแหน่งที่น้อยที่สุดของสมาชิกที่มีค่ามากที่สุดการแก้ปัญหา
ของตัวอย่างนี้ ต้องวน loop สองครั้ง เนื่องจากสมาชิกตัวสุดท้ายของ myList อาจ
เก็บค่าที่มากที่สุดไว้ ดังนั้นเราต้องวน loop ให้ครบเพื่อที่เราจะได้ค่า max ของ
myList จากนั้นวน loop อีกครั้งเพื่อหาตาแหน่งของสมาชิกตัวแรกที่เก็บค่า max
ไว้int max = Integer.MIN_VALUE;
for(int i = 0; i < myList.length; i++) {
if( myList[i] > max) max = myList[i];
}
for(int i = 0; i < myList.length; i++) {
if(myList[i] == max) {
System.out.println( i );
break;
}
}
11. การคัดลอก Arrays
บ่อยครั้ง เราต้องการคัดลอกข้อมูลใน Array ทั้งหมดหรือบางส่วนของมัน แต่ถ้าเราใช้
statement แบบข้างล่าง การคัดลอกจะไม่ได้เกิดขึ้นจริง ๆ
int myList1 = {1, 2, 3, 4, 5};
int myList2 = {6, 7, 8, 9, 10};
myList1 = myList2;
เมื่อ code สาหรับการสร้าง Array myList1 และ myList2 2 บรรทัดแรกด้านบน ถูก
เรียกทางาน โปรแกรมจะทาการจองเนื้อที่ในหน่วยความจา 2 พื้นที่ พื้นที่แรกสาหรับเก็บข้อมูล
1, 2, 3, 4, และ 5 ของ ArraymyList1 และ พื้นที่ที่ 2 สาหรับเก็บข้อมูล 6, 7, 8, 9
และ 10 ของ Array myList2 ดังรูปด้านล่างโดย myList1 จะถูกใช้อ้างอิงไปยังพื้นที่
แรก และ myList2 จะถูกใช้อ้างอิงไปยังพื้นที่หน่วยความจาที่ 2เป้าหมายที่เราต้องการ คือ
เราต้องการคัดลอกค่าของแต่ละสมาชิกของ myList2 มาเก็บไว้ที่หน่วยความจา myList1
ดังรูปด้านล่าง
1
2
3
4
5
12. int myList1 = {1, 2, 3, 4, 5};
อ้างอิง myList1
myList1[0]
myList1[1]
myList1[2]
myList1[3]
myList1[4]
myList2[0] 6
7
8
9
10
int myList2 = {6, 7, 8, 9, 10};
myList2
myList2[1]
myList2[2]
myList2[3]
myList2[4]
13. อ้างอิง
6
7
8
9
10
int myList1 = {1, 2, 3, 4, 5};
อ้างอิง myList1
myList1[0]
myList1[1]
myList1[2]
myList1[3]
myList1[4]
myList2[0] 6
7
8
9
10
int myList2 = {6, 7, 8, 9, 10};
myList2
myList2[1]
myList2[2]
myList2[3]
myList2[4]
14. อ้างอิงในการบรรลุเป้าหมายข้างต้น เราต้องระวังไม่ใช้คาสั่งในลักษณะต่อไปนี้
myList1 = myList2; เพราะคาสั่งดังกล่าวเป็นแค่การกาหนดการอ้างอิงของ
myList1 ให้อ้างอิงไปเนื้อที่หน่วยของจาเดียวกันกับ myList2 เท่านั้น (สังเกตค่าที่
เก็บใน myList1 ไม่ได้เปลี่ยนไป ในรูปด้านล่าง) ไม่ใช่การคัดลอกค่าไปยัง
หน่วยความจาแรก
อย่างที่คาดหวัง และเนื่องจาก myList1 ไม่ได้ถูกใช้อ้างอิงไปยัง
หน่วยความจาแรกแล้ว พื้นที่หน่วยความจาแรกก็
จะถูก Java ลบไปในที่สุด เพราะมันเข้าใจว่า ไม่มีใครใช้เนื้อที่ส่วนนี้แล้ว
ดังนั้น ถ้าหากเราต้องการคัดลอกค่าจาก Array หนึ่งมายังอีก Array
หนึ่ง เราอาจเลือกวิธีคัดลอกทีละค่าโดยใช้ loop ดังแสดงด้านล่าง
for(int i = 0; i < myList2.length; i++) {
myList1[i] = myList2[i];
}
15. หรือ เราอาจใช้ method ที่ Java เตรียมให้อยู่แล้วชื่อ System.arraycopy
โดยมี syntax ดังนี้:-
System.arraycopy(sourceArray, sourceIndex, targetArray,
targetIndex, num);
o sourceArray คือ ชื่อ Array ที่เราอยากให้เป็นต้นแบบ
o targetArray คือ ชื่อ Array ที่เราอยากคัดลอกค่าเข้ามาใส่
o sourceIndex คือ ตาแหน่งของ sourceArray ที่เราอยากคัดลอกค่าไป
o targetIndex คือ ตาแหน่งของ targetArray ที่เราอยากนาค่าที่คัดลอกมาใส่
ไว้
o num คือ จานวนที่อยากคัดลอก
เช่น ถ้าเราอยากคัดลอกค่าใน myList2 มาที่ myList1 ทั้งหมดโดยใช้
arraycopy เรา ทาได้ดังนี้:-
16. System.arraycopy(myList2, 0, myList1, 0, myList2.length);
myList2[0] 6
7
8
9
10
int myList2 = {6, 7, 8, 9, 10};
myList2
myList2[1]
myList2[2]
myList2[3]
myList2[4]
1 อ้างอิง
2
3
4
5
อ้างอิง
17. myList1การเรียงคาจากน้อยไปมากใน Array (Sort)
เนื่องจากการเรียงค่าใน Array ถูกนาไปใช้ในการแก้ปัญหาต่าง ๆ บ่อย ๆ, Java จึง
เตรียม method ไว้ให้สาหรับการเรียงค่า Array ของ int, double, char,
short, long และ float ตัวอย่างดัง code ด้านล่างdouble [] numbers
= {6.0, 4.4, 1.9, 2.9, 3.4, 3.5};
java.util.Arrays.sort(numbers);
char [] chars = {'a', 'A', '4', 'F', 'D', 'P'};
java.util.Arrays.sort(chars);
Array 2 มิติ (Two Dimensional Array)
Array ที่ได้กล่าวมาข้างต้นทั้งหมด เป็น Array มิติเดียว ซึ่ง บางครั้งการเก็บข้อมูล
ทั้งหมดลงใน Array มิติ
เดียวจะทาให้การเข้าถึงยุ่งยาก เช่น สมมตว่า เราต้องเก็บข้อมูลคะแนนของ
นิสิต 4 กลุ่ม กลุ่มละ 30 คนใน Array
18. หนึ่งมิติ เราต้องประกาศ Array ที่มีขนาดเท่ากับ 4 x 30 = 120 เพื่อเก็บคะแนน
ทั้งหมด และ เราต้องรู้ว่าสมาชิก
ตาแหน่งที่ 0-29 เก็บคะแนนของนิสิตกลุ่มแรก ตาแหน่งที่ 30-59 เก็บของกลุ่มที่
สอง ตาแหน่งที่ 60-89 เก็บของ
กลุ่มที่สาม และ 90-119 เก็บของกลุ่มที่สี่ ซึ่งการกาหนดค่าหรือการอ่านค่าคะแนน
ของนิสิตทาได้ค่อนข้างลาบาก
เพราะ เราต้องคานวณหาตาแหน่งใน Array ของนิสิตคนนี้ก่อน เช่น ถ้าเราต้องการ
เก็บคะแนนของนิสิตคนที่ 10
ของกลุ่มที่ 3 เราต้องไปกาหนดค่าให้สมาชิกในตาแหน่งที่ (3 – 1) * 30 + (10 – 1) = 69
เป็นต้น
นอกจากนี้ ข้อมูลอาจมีความสัมพันธ์กัน เช่น ข้อมูลระยะทางจากเมืองหนึ่งไปยังอีกเมืองหนึ่ง ดัง
ตัวอย่าง
จะเห็นว่า ข้อมูลระยะทางข้างต้นควรจะถูกเก็บในตาราง 2 มิติที่มีตาแหน่งแถวและตาแหน่งของ
หลัก
เนื่องจาก ช่วยให้เราจัดเก็บและเรียกใช้ได้ง่ายกว่ากรณีที่เก็บในตารางที่มีแถวเดียวการ
ประกาศ Array 2 มิติ
19. การประกาศ Array 2 มิตินั้นคล้ายกับการประกาศ Array หนึ่งมิติมาก
เพียงแต่เติมวงเล็บก้ามปูเข้าไป
ดังนี้: ชนิดของข้อมูล [ ][ ] ชื่อ_Array;
ในทานองเดียวกัน การจองเนื้อที่ในหน่วยความจาสาหรับ Array 2 มิติ เรา
จาเป็นต้องระบุขนาดของ
Array ทั้ง 2 มิติ (ระบุทั้งจานวนแถว และ หลัก) ซึ่งสามารถทาได้โดยใช้
syntax ดังนี้:-
ชื่อ_Array = new ชนิดของข้อมูล [จานวนแถว][จานวนหลัก];
ตัวอย่าง การประกาศ Array 2 มิติชื่อ Scores เพื่อเก็บค่าทศนิยม 4 x 3 ค่า:
double [] [] Scores;
Scores = new double[4][3];
ตัวอย่างข้างต้นสามารถถูกเขียนให้อยู่ในบรรทัดเดียวได้ ดังนี้:-
double [] [] Scores = new double[4][3];
การเข้าถึงสมาชิกใน Array 2 มิติ
20. การอ่านค่าหรือกาหนดค่าให้สมาชิกใน Array 2 มิติต้องระบุตาแหน่งของ
แถวและหลักทั้งสองตัว ดัง
ตัวอย่างต่อไปนี้:-
Scores[2][25] = 10.0; // กาหนดให้สมาชิกในแถวหมายเลข 2 และ หลัก
หมายเลข 25
// ของ Scores มีค่าเท่ากับ 10.0 (หมายเลขแถวและหลักของทุก ๆ
// Array เริ่มที่ 0)
การก กาหนดค่าตั้งต้นให้สมาชิกใน Array 2 มิติ
เราสามารถกาหนดค่าเริ่มต้นให้สมาชิกใน Array หลังจากเราสร้าง Array 2 มิติแล้ว
ดังตัวอย่างต่อไปนี้
Scores[0][0] = 1; Scores[0][1] = 2; Scores[0][2] = 3;
Scores[1][0] = 4; Scores[1][1] = 5; Scores[1][2] = 6;
Scores[2][0] = 7; Scores[2][1] = 8; Scores[2][2] = 9;
Scores[3][0] = 10; Scores[3][1] = 11; Scores[3][2] = 12;
21. ซึ่งเราสามารถเขียน statement 12 statement ข้างต้นในรูปแบบย่อได้
ดังนี้:-
int [ ][ ] Scores = { {1, 2, 3},
{4, 5, 6},
{7, 8, 9},
{10, 11, 12} };Array ที่มีแถวไม่เท่ากัน (Ragged Array)
Java ยอมให้ เราสร้าง Array 2 มิติที่มีขนาดของแต่ละแถวไม่เท่ากันได้ ดังตัวอย่างด้านล่าง
int[ ][ ] matrix = { {1, 2, 3, 4, 5},
{2, 3, 4, 5},
{3, 4, 5},
{4, 5},
{5} };
จานวนแถวของ Array จะถูกเก็บใน field ชื่อ length ของ Array ดั้งนั้น
matrix.length จะเก็บค่า 5 ไว้
นอกจากนี้ ในแต่ละแถวยังมี field ชื่อ length เก็บขนาดของแต่ละแถว (หรือ จานวนหลัก
ของแต่ละแถว) นั่นคือ
22. matrix[ i ].length จะเก็บค่าจานวนของหลักในแถวหมายเลขที่ i ไว้ ดังตาราง
matrix[0].length เก็บจานวนหลักของแถวหมายเลข 0 ซึ่งคือ 5
matrix[1].length เก็บจานวนหลักของแถวหมายเลข 1 ซึ่งคือ 4
matrix[2].length เก็บค่า 3, matrix[3].length เก็บค่า 2,
matrix[4].length เก็บค่า 1
ตัวอย่างที่ 6: พิมพ์ค่าของสมาชิกทุกตัวใน Array 2 มิติ
// ให้นิสิตสังเกตการใช้i และ j ที่ถูกใช้ ทั้งสาหรับควบคุม loop และ สาหรับเข้าถึงสมาชิก
ของ matrix
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) { // matrix[i].length คือ
จานวนหลักของแถวที่ i
System.out.println(matrix[i][j]); // พิมพ์ค่าสมาชิกแถวที่ i หลักที่ j ของ
matrix
}
}
23. ตัวอย่างที่ 7: กาหนดค่าเริ่มต้นใน Array 2 มิติ
ตัวอย่างนี้จะกาหนดค่าเริ่มต้นให้ทุกสมาชิกของ Array โดยจะกาหนดให้สมาชิกตาแหน่งที่ i
หลักที่ j มีค่า
เท่ากับ 10 * i + j ดังนี้:-
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = 10 * i + j;
}
}ตัวอย่างที่ 8: หาค่าผลบวกของค่าของสมาชิกทุกตัวในแต่ละแถวของ Array 2 มิติ
int sum = 0;
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) {
sum += matrix[i][j];
}
System.out.println( sum );
sum = 0;
}
ให้นิสิตสังเกต sum = 0; ในบรรทัดรองสุดท้าย ซึ่งมีความจาเป็นต้องมี เนื่องจาก
เราต้องการหาผลบวก
24. ของแต่ละแถว ดังนั้น หลังจากหาและแสดงค่าผลรวมของแถวที่ i แล้ว เราต้อง
กาหนดค่า sum ให้เป็น 0 ใหม่ให้
พร้อมสาหรับหาค่าผลรวมของแถวถัดไป
ตัวอย่างที่ 9: หาค่าที่มากที่สุดใน Array 2 มิติ
int max = Integer.MIN_VALUE;
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) {
if( matrix[i][j] > max)
max = matrix[i][j];
}
}
System.out.println( max );
25. ตัวอย่งที่ 10: หาตาแหน่งที่น้อยที่สุดของสมาชิกที่มีค่ามากที่สุด 2 มิติ
การแก้ปัญหาของตัวอย่างนี้เหมือนในตัวอย่างที่ 5 เราต้องวน loop ให้ตรวจสอบสมาชิกทุกตัวให้ครบ
เพื่อที่เราจะได้ค่า max ของ matrix ก่อน จากนั้นวน loop อีกครั้งเพื่อหาตาแหน่งของสมาชิกตัว
แรกที่เก็บค่า
max ไว้
int max = Integer.MIN_VALUE;
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) {
if( matrix[i][j] > max)
max = matrix[i][j];
}
}for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) {
if( matrix[i][j] == max) {
System.out.println( i + " " + j );
break;
}
}
}