บทนำ: เมื่อข้อมูลและโค้ดมีมาก
จนถึงตอนนี้เราเขียนโปรแกรมที่ ข้อมูลน้อย และ โค้ดไม่ซับซ้อน แต่ในชีวิตจริง:
- ข้อมูล: ต้องจัดการ หลายร้อยหลายพัน records
- โค้ด: ต้องทำ งานเดียวกันซ้ำๆ แต่ใช้ข้อมูลต่างกัน
Array และ Function คือเครื่องมือที่ช่วยให้:
- จัดการข้อมูลหลายๆ ตัวได้อย่างเป็นระเบียบ
- เขียนโค้ด ครั้งเดียว ใช้หลายครั้ง (Code Reuse)
- แยก logic ให้ชัดเจนและ ดูแล้วเข้าใจง่าย (Maintainability)
- บทนำ: เมื่อข้อมูลและโค้ดมีมาก
- Array: เก็บข้อมูลหลายตัว
- Array คืออะไร?
- การสร้าง Array
- วิธี 1: ประกาศและเก็บค่า
- วิธี 2: ประกาศและกำหนดค่าพร้อมกัน (Array Literal)
- การใช้ Array: อ่าน/แสดงผล
- ตัวอย่าง 1: หาค่าเฉลี่ย
- ตัวอย่าง 2: หาค่ามากสุด/น้อยสุด
- ตัวอย่าง 3: นับจำนวนค่าที่เป็นไปตามเงื่อนไข
- Enhanced for Loop: วนลูป Array ง่ายๆ
- 2D Array: Array ของ Array
- ตัวอย่าง: คำนวณคะแนนเฉลี่ยของแต่ละนักศึกษา
- Function: ทำสิ่งเดียวกันซ้ำๆ ครั้ง
- Function คืออะไร?
- โครงสร้าง Function
- ตัวอย่าง 1: Function บวกสองจำนวน
- ตัวอย่าง 2: Function ที่ไม่มี return value
- ตัวอย่าง 3: Function ที่ไม่มี Parameter
- ตัวอย่าง 4: Function ที่มี Array เป็น Parameter
- ตัวอย่าง 5: Function ที่มี Multiple Parameters
- Code Reuse: หลักการเขียนโค้ดที่ใช้ซ้ำได้
- ปัญหา: ทำสิ่งเดียวกันซ้ำๆ
- วิธี: ใช้ Function (Code Reuse)
- การแยก Logic: Separate Concerns
- ปัญหา: โค้ดขึ้นหนึ่งที่
- วิธี: แยก Logic ออกเป็น Functions
- ตัวอย่าง: โปรแกรมสมบูรณ์ที่แยก Logic
- ข้อดีของการแยก Logic:
- Best Practices: หลักเกณฑ์การเขียนโค้ดดี
- 1. Function ควรทำ 1 งานเท่านั้น
- 2. Function names ควรบ่งบอกว่าทำอะไร
- 3. Naming Convention
- สรุป: Array, Function, Code Reuse
- ตัวอย่างการใช้ทั้งหมด: Mini Grade Management System
Array: เก็บข้อมูลหลายตัว
Array คืออะไร?
Array คือ ชุดตัวแปร ที่มี ชื่อเดียวกัน แต่ ต่างกันที่ index (ตำแหน่ง)
คิดได้ว่า Array = ชั้นวางหนังสือที่มีช่องแต่ละช่อง แต่ละช่องมีหมายเลข (index) เพื่อบอกว่าหนังสือเล่มไหนอยู่ช่องไหน
textArray: scores (คะแนนของ 5 นักศึกษา)
Index: 0 1 2 3 4
┌────┬────┬────┬────┬────┐
Value: │ 85 │ 90 │ 78 │ 92 │ 88 │
└────┴────┴────┴────┴────┘
scores[0] = 85
scores[1] = 90
scores[2] = 78
scores[3] = 92
scores[4] = 88
ข้อสำคัญ: Index เริ่มจาก 0 ไม่ใช่ 1
การสร้าง Array
วิธี 1: ประกาศและเก็บค่า
java// ประกาศ array ที่มี 5 ช่อง
int[] scores = new int[5];
// กำหนดค่า
scores[0] = 85;
scores[1] = 90;
scores[2] = 78;
scores[3] = 92;
scores[4] = 88;
วิธี 2: ประกาศและกำหนดค่าพร้อมกัน (Array Literal)
javaint[] scores = {85, 90, 78, 92, 88};
String[] names = {"John", "Jane", "Bob", "Alice", "Tom"};
double[] prices = {10.5, 20.3, 15.8, 25.0};
boolean[] isActive = {true, false, true};
การใช้ Array: อ่าน/แสดงผล
javapublic class ArrayDemo {
public static void main(String[] args) {
int[] scores = {85, 90, 78, 92, 88};
// อ่านค่าจาก array
System.out.println("First score: " + scores[0]); // 85
System.out.println("Last score: " + scores[4]); // 88
// ทราบขนาด array
System.out.println("Array size: " + scores.length); // 5
// แสดงทั้งหมด
for (int i = 0; i < scores.length; i++) {
System.out.println("Score " + (i+1) + ": " + scores[i]);
}
}
}
Output:
textFirst score: 85
Last score: 88
Array size: 5
Score 1: 85
Score 2: 90
Score 3: 78
Score 4: 92
Score 5: 88
ตัวอย่าง 1: หาค่าเฉลี่ย
javapublic class AverageCalculator {
public static void main(String[] args) {
int[] scores = {85, 90, 78, 92, 88};
int sum = 0;
// บวกทั้งหมด
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
// หาค่าเฉลี่ย
double average = (double) sum / scores.length;
System.out.println("Total: " + sum);
System.out.println("Average: " + average);
}
}
Output:
textTotal: 433
Average: 86.6
ตัวอย่าง 2: หาค่ามากสุด/น้อยสุด
javapublic class MinMaxFinder {
public static void main(String[] args) {
int[] scores = {85, 90, 78, 92, 88};
int max = scores[0];
int min = scores[0];
// หาค่ามากสุดและน้อยสุด
for (int i = 1; i < scores.length; i++) {
if (scores[i] > max) {
max = scores[i];
}
if (scores[i] < min) {
min = scores[i];
}
}
System.out.println("Maximum score: " + max);
System.out.println("Minimum score: " + min);
}
}
Output:
textMaximum score: 92
Minimum score: 78
ตัวอย่าง 3: นับจำนวนค่าที่เป็นไปตามเงื่อนไข
javapublic class GradeCounter {
public static void main(String[] args) {
int[] scores = {85, 90, 78, 92, 88};
int countPass = 0;
int countFail = 0;
for (int i = 0; i < scores.length; i++) {
if (scores[i] >= 80) {
countPass++;
} else {
countFail++;
}
}
System.out.println("Passed: " + countPass);
System.out.println("Failed: " + countFail);
}
}
Output:
textPassed: 4
Failed: 1
Enhanced for Loop: วนลูป Array ง่ายๆ
Java มี syntax พิเศษสำหรับ loop array เรียกว่า Enhanced for (หรือ for-each)
java// Regular for loop
for (int i = 0; i < scores.length; i++) {
System.out.println(scores[i]);
}
// Enhanced for loop - ง่ายกว่า
for (int score : scores) {
System.out.println(score);
}
ตัวอย่าง:
javapublic class EnhancedForDemo {
public static void main(String[] args) {
String[] names = {"John", "Jane", "Bob", "Alice"};
// วิธีสั้นๆ
for (String name : names) {
System.out.println("Hello, " + name);
}
}
}
Output:
textHello, John
Hello, Jane
Hello, Bob
Hello, Alice
2D Array: Array ของ Array
บ่อยครั้ง ข้อมูลเป็นตาราง (แถว x คอลัมน์) เราใช้ 2D Array
text2D Array: grades (คะแนนของ 3 นักศึกษา ในแต่ละวิชา 4 วิชา)
วิชา1 วิชา2 วิชา3 วิชา4
นศ.1 85 90 78 92
นศ.2 80 85 88 91
นศ.3 75 80 85 79
int[][] grades = {
{85, 90, 78, 92}, // นศ. 1
{80, 85, 88, 91}, // นศ. 2
{75, 80, 85, 79} // นศ. 3
};
grades[0][0] = 85 (นศ.1, วิชา1)
grades[1][2] = 88 (นศ.2, วิชา3)
grades[2][3] = 79 (นศ.3, วิชา4)
ตัวอย่าง: คำนวณคะแนนเฉลี่ยของแต่ละนักศึกษา
javapublic class StudentGradesAnalysis {
public static void main(String[] args) {
int[][] grades = {
{85, 90, 78, 92},
{80, 85, 88, 91},
{75, 80, 85, 79}
};
// คำนวณเฉลี่ยแต่ละนักศึกษา
for (int i = 0; i < grades.length; i++) {
int sum = 0;
for (int j = 0; j < grades[i].length; j++) {
sum += grades[i][j];
}
double average = (double) sum / grades[i].length;
System.out.printf("Student %d average: %.2f\n", i+1, average);
}
}
}
Output:
textStudent 1 average: 86.25
Student 2 average: 86.00
Student 3 average: 79.75
Function: ทำสิ่งเดียวกันซ้ำๆ ครั้ง
Function คืออะไร?
Function คือ ชุดของคำสั่ง ที่ทำ งานเดียวกัน ซึ่ง เขียนครั้งเดียว แต่ใช้หลายครั้ง
ลองนึกถึง เครื่องคิดเลข (Calculator) ที่มีปุ่มบวก (+) ถ้าไม่มี function เราต้องเขียนโค้ดบวก ทุกครั้งที่ต้องบวก แต่มี function เราแค่เรียก function บวก ก็เสร็จ
โครงสร้าง Function
java[access modifier] [return type] [function name]([parameters]) {
// body - โค้ดที่ทำงาน
[return value];
}
ตัวอย่าง 1: Function บวกสองจำนวน
javapublic class Calculator {
// Function: บวก
public static int add(int a, int b) {
int result = a + b;
return result;
}
public static void main(String[] args) {
// เรียก function add
int sum1 = add(5, 3); // เรียกครั้งที่ 1
int sum2 = add(10, 20); // เรียกครั้งที่ 2
int sum3 = add(100, 50); // เรียกครั้งที่ 3
System.out.println("5 + 3 = " + sum1);
System.out.println("10 + 20 = " + sum2);
System.out.println("100 + 50 = " + sum3);
}
}
Output:
text5 + 3 = 8
10 + 20 = 30
100 + 50 = 150
วิธีทำงาน:
- เรียก
add(5, 3) - a = 5, b = 3
- result = 5 + 3 = 8
- return 8
- sum1 = 8
ตัวอย่าง 2: Function ที่ไม่มี return value
javapublic class Greetings {
// Function: ทักทาย (ไม่ return ค่า - ใช้ void)
public static void greet(String name) {
System.out.println("Hello, " + name + "!");
System.out.println("Welcome to Java!");
}
public static void main(String[] args) {
greet("John");
greet("Jane");
greet("Bob");
}
}
Output:
textHello, John!
Welcome to Java!
Hello, Jane!
Welcome to Java!
Hello, Bob!
Welcome to Java!
ตัวอย่าง 3: Function ที่ไม่มี Parameter
javapublic class RandomNumber {
// Function: สุ่มเลข
public static int getRandomNumber() {
return (int) (Math.random() * 100) + 1; // 1-100
}
public static void main(String[] args) {
System.out.println("Random number 1: " + getRandomNumber());
System.out.println("Random number 2: " + getRandomNumber());
System.out.println("Random number 3: " + getRandomNumber());
}
}
Output (ตัวอย่าง):
textRandom number 1: 42
Random number 2: 87
Random number 3: 15
ตัวอย่าง 4: Function ที่มี Array เป็น Parameter
javapublic class ArrayFunctions {
// Function: หาค่าเฉลี่ยของ array
public static double calculateAverage(int[] numbers) {
int sum = 0;
for (int num : numbers) {
sum += num;
}
return (double) sum / numbers.length;
}
// Function: หาค่ามากสุด
public static int findMax(int[] numbers) {
int max = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
}
return max;
}
public static void main(String[] args) {
int[] scores = {85, 90, 78, 92, 88};
double avg = calculateAverage(scores);
int max = findMax(scores);
System.out.printf("Average: %.2f\n", avg);
System.out.println("Maximum: " + max);
}
}
Output:
textAverage: 86.60
Maximum: 92
ตัวอย่าง 5: Function ที่มี Multiple Parameters
javapublic class StudentGrading {
// Function: ตัดเกรดจากคะแนน
public static String getGrade(int score) {
if (score >= 80) return "A";
else if (score >= 70) return "B";
else if (score >= 60) return "C";
else if (score >= 50) return "D";
else return "F";
}
// Function: แสดงรายงานนักศึกษา
public static void printStudentReport(String name, int score) {
String grade = getGrade(score);
System.out.printf("Name: %s, Score: %d, Grade: %s\n", name, score, grade);
}
public static void main(String[] args) {
printStudentReport("John", 85);
printStudentReport("Jane", 75);
printStudentReport("Bob", 65);
printStudentReport("Alice", 92);
}
}
Output:
textName: John, Score: 85, Grade: A
Name: Jane, Score: 75, Grade: B
Name: Bob, Score: 65, Grade: C
Name: Alice, Score: 92, Grade: A
Code Reuse: หลักการเขียนโค้ดที่ใช้ซ้ำได้
ปัญหา: ทำสิ่งเดียวกันซ้ำๆ
java// ❌ ไม่ใช้ function - ต้องเขียนซ้ำ
public static void main(String[] args) {
// คำนวณเฉลี่ยครั้งที่ 1
int[] scores1 = {85, 90, 78, 92, 88};
int sum1 = 0;
for (int score : scores1) sum1 += score;
double avg1 = (double) sum1 / scores1.length;
System.out.println("Average: " + avg1);
// คำนวณเฉลี่ยครั้งที่ 2 - ต้องเขียนโค้ดเดิมอีก!
int[] scores2 = {75, 80, 82};
int sum2 = 0;
for (int score : scores2) sum2 += score;
double avg2 = (double) sum2 / scores2.length;
System.out.println("Average: " + avg2);
// ครั้งที่ 3 - ยาวมาก!
int[] scores3 = {95, 96, 97, 98};
int sum3 = 0;
for (int score : scores3) sum3 += score;
double avg3 = (double) sum3 / scores3.length;
System.out.println("Average: " + avg3);
}
วิธี: ใช้ Function (Code Reuse)
java// ✓ ใช้ function - เขียนครั้งเดียว ใช้หลายครั้ง
public static double calculateAverage(int[] numbers) {
int sum = 0;
for (int num : numbers) sum += num;
return (double) sum / numbers.length;
}
public static void main(String[] args) {
int[] scores1 = {85, 90, 78, 92, 88};
System.out.println("Average: " + calculateAverage(scores1));
int[] scores2 = {75, 80, 82};
System.out.println("Average: " + calculateAverage(scores2));
int[] scores3 = {95, 96, 97, 98};
System.out.println("Average: " + calculateAverage(scores3));
}
ข้อดี Code Reuse:
- ❌ ลบโค้ดซ้ำ
- ✅ ง่ายต่อการ maintain (แก้ที่เดียว มีผลทุกที่)
- ✅ ลดโอกาส bugs (ไม่ต้องเขียนซ้ำ)
- ✅ โค้ดอ่านง่ายและสั้น
การแยก Logic: Separate Concerns
ปัญหา: โค้ดขึ้นหนึ่งที่
java// ❌ โค้ดยาวและผสมกัน - ยากต่อการเข้าใจ
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// รับข้อมูล
System.out.print("Enter name: ");
String name = input.nextLine();
System.out.print("Enter score 1: ");
int score1 = input.nextInt();
System.out.print("Enter score 2: ");
int score2 = input.nextInt();
System.out.print("Enter score 3: ");
int score3 = input.nextInt();
// คำนวณเฉลี่ย
int sum = score1 + score2 + score3;
double average = (double) sum / 3;
// ตัดเกรด
String grade;
if (average >= 80) grade = "A";
else if (average >= 70) grade = "B";
else grade = "C";
// แสดงผล
System.out.println("Name: " + name);
System.out.println("Average: " + average);
System.out.println("Grade: " + grade);
input.close();
}
วิธี: แยก Logic ออกเป็น Functions
java// ✓ แยก logic ให้ชัดเจน
// Function 1: รับข้อมูล
public static void getStudentData() {
// ...
}
// Function 2: คำนวณเฉลี่ย
public static double calculateAverage(int score1, int score2, int score3) {
return (double) (score1 + score2 + score3) / 3;
}
// Function 3: ตัดเกรด
public static String getGrade(double average) {
if (average >= 80) return "A";
else if (average >= 70) return "B";
else return "C";
}
// Function 4: แสดงผล
public static void displayResult(String name, double average, String grade) {
System.out.println("Name: " + name);
System.out.println("Average: " + average);
System.out.println("Grade: " + grade);
}
ตัวอย่าง: โปรแกรมสมบูรณ์ที่แยก Logic
javaimport java.util.Scanner;
public class StudentSystem {
// Function: คำนวณเฉลี่ย
public static double calculateAverage(int[] scores) {
int sum = 0;
for (int score : scores) {
sum += score;
}
return (double) sum / scores.length;
}
// Function: ตัดเกรด
public static String getGrade(double average) {
if (average >= 80) return "A";
else if (average >= 70) return "B";
else if (average >= 60) return "C";
else return "F";
}
// Function: แสดงรายงาน
public static void displayReport(String name, int[] scores, double average, String grade) {
System.out.println("\n=== Student Report ===");
System.out.println("Name: " + name);
System.out.print("Scores: ");
for (int score : scores) {
System.out.print(score + " ");
}
System.out.println();
System.out.printf("Average: %.2f\n", average);
System.out.println("Grade: " + grade);
}
// Function: main - ประสาน logic
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// รับข้อมูล
System.out.print("Enter student name: ");
String name = input.nextLine();
System.out.print("Enter number of scores: ");
int numScores = input.nextInt();
int[] scores = new int[numScores];
for (int i = 0; i < numScores; i++) {
System.out.print("Enter score " + (i+1) + ": ");
scores[i] = input.nextInt();
}
// คำนวณและตัดเกรด
double average = calculateAverage(scores);
String grade = getGrade(average);
// แสดงผล
displayReport(name, scores, average, grade);
input.close();
}
}
Output (ตัวอย่าง):
textEnter student name: John
Enter number of scores: 3
Enter score 1: 85
Enter score 2: 90
Enter score 3: 88
=== Student Report ===
Name: John
Scores: 85 90 88
Average: 87.67
Grade: A
ข้อดีของการแยก Logic:
| ข้อดี | ตัวอย่าง |
|---|---|
| อ่านง่าย | main() ชัดเจนว่าทำอะไร – รับ → คำนวณ → แสดง |
| ดูแลง่าย | ต้องแก้ logic ใดสักอย่าง แค่ไปแก้ที่ function นั้น |
| เทสได้ | test แต่ละ function แยกกัน ไม่ต้อง run ทั้งโปรแกรม |
| ใช้ซ้ำได้ | function ที่ดีสามารถนำไปใช้ในโปรแกรมอื่นได้ |
Best Practices: หลักเกณฑ์การเขียนโค้ดดี
1. Function ควรทำ 1 งานเท่านั้น
java// ❌ ไม่ดี - function ทำหลายงาน
public static void processStudent(String name, int[] scores) {
// คำนวณเฉลี่ย
double average = ...;
// ตัดเกรด
String grade = ...;
// เซฟลง database
// ...
// ส่ง email
// ...
}
// ✓ ดี - แต่ละ function ทำ 1 งาน
public static double calculateAverage(int[] scores) { ... }
public static String getGrade(double average) { ... }
public static void saveToDatabase(String name, double average) { ... }
public static void sendEmail(String email, String message) { ... }
2. Function names ควรบ่งบอกว่าทำอะไร
java// ❌ ไม่ชัดเจน
public static int calc(int a, int b) { ... }
public static void display(String x) { ... }
// ✓ ชัดเจน
public static int calculateSum(int a, int b) { ... }
public static void displayStudentReport(String name) { ... }
3. Naming Convention
java// ✓ ตัวแปร: camelCase
int studentAge;
String firstNameOfStudent;
// ✓ Function/Method: camelCase ขึ้นด้วยตัวเล็ก
public static void calculateAverage() { }
public static int getMaxValue(int[] numbers) { }
// ✓ Class: PascalCase ขึ้นด้วยตัวใหญ่
public class StudentManagementSystem { }
public class Calculator { }
สรุป: Array, Function, Code Reuse
| หัวข้อ | ประโยชน์ | ตัวอย่าง |
|---|---|---|
| Array | จัดเก็บข้อมูลหลายตัว | int[] scores = {85, 90, 78}; |
| Function | ทำสิ่งเดียวกันซ้ำๆ | public static double avg(int[] nums) { } |
| Code Reuse | เขียนครั้งเดียว ใช้หลายครั้ง | เรียก function หลายครั้ง |
| Separation of Concerns | แยก logic ให้ชัดเจน | main() เรียก functions ต่างๆ |
ตัวอย่างการใช้ทั้งหมด: Mini Grade Management System
javaimport java.util.Scanner;
public class GradeManagementSystem {
// Constant
private static final int TOTAL_SUBJECTS = 3;
// Function: รับคะแนนนักศึกษา
public static int[] getScores(Scanner input, String studentName) {
int[] scores = new int[TOTAL_SUBJECTS];
System.out.println("\nEnter scores for " + studentName + ":");
for (int i = 0; i < TOTAL_SUBJECTS; i++) {
System.out.print("Subject " + (i+1) + ": ");
scores[i] = input.nextInt();
}
return scores;
}
// Function: คำนวณเฉลี่ย
public static double calculateAverage(int[] scores) {
int sum = 0;
for (int score : scores) {
sum += score;
}
return (double) sum / scores.length;
}
// Function: ตัดเกรด
public static String getGrade(double average) {
if (average >= 80) return "A";
else if (average >= 70) return "B";
else if (average >= 60) return "C";
else if (average >= 50) return "D";
else return "F";
}
// Function: ตรวจสอบ Pass/Fail
public static boolean isPassed(double average) {
return average >= 60;
}
// Function: แสดงรายงาน
public static void displayReport(String name, int[] scores, double average, String grade) {
System.out.println("\n=== Grade Report ===");
System.out.println("Student: " + name);
System.out.print("Scores: ");
for (int score : scores) {
System.out.print(score + " ");
}
System.out.println();
System.out.printf("Average: %.2f\n", average);
System.out.println("Grade: " + grade);
System.out.println("Status: " + (isPassed(average) ? "PASSED" : "FAILED"));
}
// Main
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter number of students: ");
int numStudents = input.nextInt();
input.nextLine(); // Clear buffer
for (int i = 0; i < numStudents; i++) {
// รับชื่อ
System.out.print("\nEnter student " + (i+1) + " name: ");
String name = input.nextLine();
// รับคะแนน
int[] scores = getScores(input, name);
// คำนวณและตัดเกรด
double average = calculateAverage(scores);
String grade = getGrade(average);
// แสดงรายงาน
displayReport(name, scores, average, grade);
}
input.close();
}
}
Output (ตัวอย่าง):
textEnter number of students: 2
Enter student 1 name: John
Enter scores for John:
Subject 1: 85
Subject 2: 90
Subject 3: 88
=== Grade Report ===
Student: John
Scores: 85 90 88
Average: 87.67
Grade: A
Status: PASSED
Enter student 2 name: Jane
Enter scores for Jane:
Subject 1: 65
Subject 2: 70
Subject 3: 60
=== Grade Report ===
Student: Jane
Scores: 65 70 60
Average: 65.00
Grade: C
Status: PASSED
