--- tags: Cmoney_Java題目 --- Java_Cmoney_Week2_介面練習 === ![](https://i.imgur.com/8HUula8.png) 1.需要的 Class --- 1.1 產生隨機資料的(隨機字串與隨機數字) --- 將裡面的方法都用成靜態,這樣使用時就不用 new 出實體。 ```java= package com.company; /** 產生隨機資料用 * */ public class Input { /** 隨機產生從 min~max 長度的字串,字串由隨機的 26個英文小寫字母組成 * @param hint 跑出的提示 * @param min 隨機字串最小長度 * @param max 隨機字串最大長度 * @return String 回傳隨機字串 */ public static String randomInputString(String hint, int min, int max) { System.out.print(hint + ": "); StringBuilder str = new StringBuilder(); for (int i = 0; i < Input.random(min, max); i++) { str.append((char) Input.random(97, 122)); } System.out.println(str); return str.toString(); } /** 隨機產生從 min~max 範圍的數字 * @param hint 跑出的提示 * @param min 隨機數字最小值 * @param max 隨機數字最大值 * @return int 隨機數字 */ public static int randomInputNum(String hint,int min, int max) { System.out.print(hint + ": "); int randomNum = random(min,max); System.out.println(randomNum); return randomNum; } /** 隨機產生從 min~max 範圍的數字 * @param min 隨機數字最小值 * @param max 隨機數字最大值 * @return int 隨機數字 */ public static int random(int min, int max) { return (int) (Math.random() * (max - min + 1) + min); } } ``` 1.2 學生 --- 如果屬性都是必填的話,用建造者模式會有點多餘。 ```java= package com.company; /** * 產生學生物件用 */ public class Student { private int seat; private int score; private String name; /** * InnerBuilder * * @param builder */ private Student(Builder builder) { setSeat(builder.seat); setScore(builder.score); setName(builder.name); } public static final class Builder { private int seat; private int score; private String name; public Builder() { } public Builder setSeat(int val) { seat = val; return this; } public Builder setScore(int val) { score = val; return this; } public Builder setName(String val) { name = val; return this; } public Student build() { return new Student(this); } } // Getter and Setter public int getSeat() { return seat; } public void setSeat(int seat) { this.seat = seat; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 輸出學生物件的樣子 @Override public String toString() { return "座號: " + seat + " 成績: " + score + " 姓名: " + name; } } ``` 1.3 學生陣列物件 --- 1. 創建比較器介面再到主程式使用匿名類別 2. 創建篩選器介面再到主程式使用匿名類別 ```java= package com.company; /** 創造學生陣列用,用來儲存學生物件 * */ public class StudentArray { private Student[] arr; private int count; /** 比較器介面 * */ public interface Comparator { public int compare(Student s1, Student s2); } /** 篩選器介面 * */ public interface Filter { public boolean filter(Student student); } /** * 建構子 */ public StudentArray() { this.arr = new Student[2]; this.count = 0; } /** 將學生物件加到學生陣列的最後一個 * @param student 要加入的學生物件 */ public void add(Student student) { // 如果加入為 null if (student == null) { return; } // 如果加入時,學生陣列已經滿了,需要增加空間 if (this.count == this.arr.length) { doubleArr(); } // 將學生物件加到學生陣列中 this.arr[count++] = student; } /** 使用 index 找到該位置的學生,並回傳此學生物件 * @param index 要找的位置 * @return Student 回傳學生物件 */ public Student getStudentByIndex(int index) { // 如果 index < 0 或大於現有的學生物件數量,則回傳 null if (index < 0 || index >= count) { return null; } // 回傳該位置的學生物件 return this.arr[index]; } /** 使用篩選器找到符合條件的學生,加到一個暫時的 StudentArray ,並回傳 StudentArray * @param filter 使用的篩選器 * @return StudentArray 回傳 StudentArray */ public StudentArray where(Filter filter) { // 創建一個暫時的學生陣列 StudentArray tmpArr = new StudentArray(); // 將符合篩選器的學生加入到暫時的學生陣列 for (int i = 0; i < this.count; i++) { Student tmpStudent = this.arr[i]; if (filter.filter(tmpStudent)) { tmpArr.add(tmpStudent); } } return tmpArr; } /** 使用比較器排序,並回傳 StudentArray * @param c 使用的比較器 * @return StudentArray 回傳 StudentArray */ public StudentArray sort(Comparator c) { // 創建一個暫時的學生陣列 StudentArray tmpArr = new StudentArray(); // 將遠本的學生陣列深度拷貝到暫時的學生陣列 for (int i = 0; i < this.count; i++) { tmpArr.add(this.arr[i]); } // 將暫時的學生陣列進行泡沫排序 for (int i = 0; i < this.count - 1; i++) { for (int j = 0; j < this.count - i - 1; j++) { if (c.compare(tmpArr.getStudentByIndex(j), tmpArr.getStudentByIndex(j + 1)) > 0) { tmpArr.swap(j, j + 1); } } } return tmpArr; } /** 回傳現在有幾個學生 * @return int 學生數量 */ public int length() { return this.count; } /** 將學生陣列空間乘以兩倍,並將東西轉移到新陣列 * */ private void doubleArr() { // 創建一個暫時的學生陣列 Student[] tmpArr = new Student[arr.length * 2]; // 將遠本的學生陣列深度拷貝到暫時的學生陣列 for (int i = 0; i < arr.length; i++) { tmpArr[i] = this.arr[i]; } this.arr = tmpArr; } /** 將學生陣列的兩個學生物件互換位置 * @param i1 * @param i2 */ private void swap(int i1, int i2) { Student tmp = this.arr[i1]; this.arr[i1] = this.arr[i2]; this.arr[i2] = tmp; } // Getter and Setter public Student[] getArr() { return arr; } public void setArr(Student[] arr) { this.arr = arr; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } } ``` 2.主程式 --- ```java= package com.company; import java.util.Random; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 學生資料庫物件 StudentArray studentArray = new StudentArray(); // 讓使用者持續輸入 while (true) { System.out.println("請輸入功能"); // 讓使用者輸入功能編號 int opt = sc.nextInt(); // 吃掉上面的換行符號 sc.nextLine(); switch (opt) { // 新增一名學生到學生陣列,使用 Input 自動產生座號、成績、姓名 case 1: studentArray.add(new Student.Builder() .setSeat(Input.randomInputNum("自動產生座號: ", 1, 100)) .setScore(Input.randomInputNum("自動產生成績: ", 0, 100)) .setName(Input.randomInputString("自動產生姓名: ", 2, 3)) .build() ); break; // 排序學生陣列 case 2: System.out.println("請輸入排序方法編號: 1.依照座號 2.依照成績 3.依照姓名 "); // 讓使用者輸入篩選規則編號 int sortFuncNum = sc.nextInt(); // 吃掉上面的換行符號 sc.nextLine(); // 排序學生陣列(依據剛才的選擇編號 sortFuncNum) sortFunc(studentArray, sortFuncNum); // 印出學生陣列內所有學生物件 printAllStu(studentArray); break; case 3: // 隨機排序學生陣列 randomSequence(studentArray); // 印出學生陣列內所有學生物件 printAllStu(studentArray); break; case 4: // 印出學生陣列內所有學生物件 printAllStu(studentArray); break; case 5: // 離開系統 System.exit(0); break; } } } /** 印出學生陣列內所有學生物件 * @param studentArray */ public static void printAllStu(StudentArray studentArray) { // 迴圈掃過學生陣列內所有物件並印出 for (int i = 0; i < studentArray.getCount(); i++) { System.out.println(studentArray.getStudentByIndex(i)); } // 分隔線 System.out.println("--------------------------------"); } /** 排序學生陣列的各種方法 * @param studentArray 要排序的學生陣列 * @param sortFuncNum 要選擇排序的規則 */ public static void sortFunc(StudentArray studentArray, int sortFuncNum) { // 創建一個暫時的學生陣列 StudentArray result; // 看輸入哪個規則編號決定排序方式 switch (sortFuncNum) { // 使用座號排列(由小到大) case 1: // 將排序後的學生陣列放到暫時的學生陣列 result = studentArray.sort((s1, s2) -> s1.getSeat() - s2.getSeat()); // 將原本的學生陣列設置成暫時的學生陣列(排好的) studentArray.setArr(result.getArr()); break; // 使用成績排列(由小到大) case 2: // 將排序後的學生陣列放到暫時的學生陣列 result = studentArray.sort(((s1, s2) -> s1.getScore() - s2.getScore())); // 將原本的學生陣列設置成暫時的學生陣列(排好的) studentArray.setArr(result.getArr()); break; // 使用姓名排列(由a到z) case 3: // 將排序後的學生陣列放到暫時的學生陣列 result = studentArray.sort(((s1, s2) -> s1.getName().compareTo(s2.getName()))); // 將原本的學生陣列設置成暫時的學生陣列(排好的) studentArray.setArr(result.getArr()); break; // 若輸入沒有此規則編號 default: System.out.println("沒有此排序方法編號"); break; } } /** 將學生物件重新打亂排序 * @param studentArray 要打亂順序的學生陣列 */ public static void randomSequence(StudentArray studentArray) { // 將學生陣列淺拷貝到 sequence Student[] sequence = studentArray.getArr(); // 創建隨機物件 Random random = new Random(); // 使用迴圈將每個打亂順序 for (int i = 0; i < studentArray.getCount(); i++) { // 隨機產生 0 ~ (studentArray.getCount() - 1) 的正整數 int p = random.nextInt(studentArray.getCount()); // 創建暫時的學生物件用來保留學生 ( sequence[i] ) Student tmp = sequence[i]; // 將學生 ( sequence[i] ) 換成隨機位置的學生( sequence[p] ) sequence[i] = sequence[p]; // 將隨機位置的學生( sequence[p] ) 換成學生 ( sequence[i] ) sequence[p] = tmp; } // 將重新排序的學生陣列賦予到學生陣列 studentArray.setArr(sequence); } } ```