앞선 프로젝트의 틀은 그대로 유지하되 배열로 구현하던 부분을 리스트를 이용하여 구현해 보도록 하겠다.
- StudentApp
👉 Controller 부분에서는 바뀌는 부분이 없기 때문에 생략한다.
- StudentService
👉 배열을 리스트로 변경하면서 count 체크를 할 필요가 없어졌다.
👉 삭제 후에는 알아서 리스트 size가 줄어들기 때문에 조정할 필요가 없다.
👉 리스트는 학생을 성적순으로 정렬하기 위해 sort 메서드를 사용할 수 있는데 정렬 대상인 클래스가
인터페이스 Comparable를 구현해야 한다.
public class StudentService {
// 학생 객체를 저장할 리스트 생성
// 제네릭 타입 : Student
private List<Student> students = new ArrayList<Student>();
// 정렬한 학생 객체를 저장할 리스트 생성
private List<Student> sortedStudents = new ArrayList<Student>();
// test students
{
students.add(new Student(students.size() + 1));
students.add(new Student(students.size() + 1));
students.add(new Student(students.size() + 1));
students.add(new Student(students.size() + 1));
students.add(new Student(students.size() + 1));
}
// 기능 구현
// Creat
public void register() throws MyRangeException{
// 새로운 학생 등록
System.out.println();
String name = nextLine("등록하실 학생의 이름을 입력해 주세요. >> ");
int korean = confirmScore(nextInt("등록하실 학생의 국어 점수를 입력해 주세요. >> "));
int math = confirmScore(nextInt("등록하실 학생의 수학 점수를 입력해 주세요. >> "));
int english = confirmScore(nextInt("등록하실 학생의 영어 점수를 입력해 주세요. >> "));
students.add(new Student(students.size() + 1, name, korean, math, english));
// 정렬
sortStudents();
System.out.println("학생이 등록 되었습니다. ");
}
// Read
public void list() {
System.out.println();
existStudent();
switch (nextInt("조회하실 목록을 선택해 주세요. 1. 전체 목록 2. 석차별 조회 >> ")) {
case 1:
listAll();
break;
case 2:
listRank();
break;
default:
break;
}
}
private void listAll() {
System.out.println();
System.out.println(" 학생 번호 " + " | " + " 이름 " + " | " + " 국어 점수 " + " | " + " 수학 점수 " + " | " + " 영어 점수 " + " | " + " 총점 " + " | " + " 평균 ");
for (int i = 0; i < students.size(); i++) {
System.out.printf("%s%n", students.get(i));
}
}
private void listRank() {
System.out.println(" 석차 번호 " + " | " + " 학생 번호 " + " | " + " 이름 " + " | " + " 국어 점수 " + " | " + " 수학 점수 " + " | " + " 영어 점수 " + " | " + " 총점 " + " | " + " 평균 ");
for (int i = 0; i < sortedStudents.size(); i++) {
System.out.printf("%5d %6c %s%n", (i + 1), ' ', sortedStudents.get(i));
}
}
// Update
public void modify() {
existStudent();
listAll();
System.out.println();
int no = nextInt("수정할 학생의 번호를 입력하세요. >> ");
System.out.println();
System.out.println(" 학생 번호 " + " | " + " 이름 " + " | " + " 국어 점수 " + " | " + " 수학 점수 " + " | " + " 영어 점수 " + " | " + " 총점 " + " | " + " 평균 ");
Student target = findBy(no);
System.out.println();
switch (nextInt("수정할 영역을 선택해주세요. 1. 이름 | 2. 국어 점수 | 3. 수학 점수 | 4. 영어 점수 >> ")) {
case 1:
target.setName(nextLine("변경된 이름을 입력하세요. >> "));
System.out.println("변경이 완료되었습니다. ");
break;
case 2:
target.setKorean(nextInt("변경된 국어 점수를 입력하세요. >> "));
System.out.println("변경이 완료되었습니다. ");
break;
case 3:
target.setMath(nextInt("변경된 수학 점수를 입력하세요. >> "));
System.out.println("변경이 완료되었습니다. ");
break;
case 4:
target.setEnglish(nextInt("변경된 영어 점수를 입력하세요. >> "));
System.out.println("변경이 완료되었습니다. ");
break;
default:
break;
}
sortStudents();
listAll();
}
// Delete
public void remove() {
existStudent();
listAll();
int no = nextInt("삭제할 학생의 번호를 입력하세요. >>");
if(findBy(no) != null) {
students.remove(no);
System.out.println("삭제가 완료되었습니다.");
}
sortStudents();
listAll();
}
// 학생 번호로 학생 정보 가져오기
private Student findBy(int no) {
Student target = new Student();
for (int i = 0; i < students.size(); i++) {
if(students.get(i).getNo() == no) {
target = students.get(i);
System.out.printf("%s%n", target);
}
}
return target;
}
// 정렬된 학생 목록 만들기
private void sortStudents() {
sortedStudents.addAll(students);
Collections.sort(sortedStudents);
}
private int confirmScore(int score) throws MyRangeException {
if(score < 0 || score > 100) {
throw new MyRangeException();
}
return score;
}
private void existStudent() {
// count를 사용하지 않기 때문에 리스트가 비어있는지만 확인하면 된다.
if(students.isEmpty()) {
throw new RuntimeException("현재 등록된 학생이 없습니다.");
}
}
}
- Student
👉 리스트의 sort 를 사용하기 위해서 Comparable의 compareTo 메서드를 구현하였다.
public class Student implements Comparable<Student>{
// 학번
private int no;
// 이름
private String name;
// 국어
private int korean;
// 수학
private int math;
// 영어
private int english;
public Student() {}
public Student(int no) {
this(no, randomName(), randomScore(), randomScore(), randomScore());
}
public Student(int no, String name, int korean, int math, int english) {
setNo(no);
setName(name);
setKorean(korean);
setMath(math);
setEnglish(english);
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getKorean() {
return korean;
}
public void setKorean(int korean) {
if (korean < 0 || korean > 100) {
// System.out.println("잘못된 범위");
korean = 0;
return;
}
this.korean = korean;
}
public int getMath() {
return math;
}
public void setMath(int math) {
if (math < 0 || math > 100) {
// System.out.println("잘못된 범위");
math = 0;
return;
}
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
if (english < 0 || english > 100) {
// System.out.println("잘못된 범위");
english = 0;
return;
}
this.english = english;
}
// 점수 총합
public int sumScore() {
return getKorean() + getMath() + getEnglish();
}
// 점수 평균
public double avgScore() {
return (int) (sumScore() * 100d / 3) / 100d;
}
@Override
public String toString() {
return String.format("%5d %11s %8d %14d %12d %11d %9.2f", no, name, korean, math, english, sumScore(), avgScore());
}
// test score
static int randomScore() {
return (int)(Math.random() * 41 + 60);
}
// test name
static String randomName() {
String[] arr = {"피카츄", "라이츄", "파이리", "꼬부기", "버터플", "야도란", "피존투", "또가스"};
return arr[(int)(Math.random() * 8)];
}
@Override
public int compareTo(Student o) {
return sumScore() - o.sumScore();
}
}
- StudentUtils
👉 util 부분에서는 바뀌는 부분이 없기 때문에 생략한다.
- MyRangeException
👉 exception 부분에서는 바뀌는 부분이 없기 때문에 생략한다.
배열에서 리스트로 바뀌며 저장 공간에 대한 고려를 덜하게 된다는 장점을 가지게 되었다.
또한 배열처럼 아무것도 저장되지 않은 공간에 대한 처리를 고민하지 않아도 된다는 장점도 있다.
'JAVA > PROJECT' 카테고리의 다른 글
Project_02 : 콘솔 프로그램 Student - 배열 활용 버전 (0) | 2022.09.27 |
---|---|
Project_01 : 상속과 인터페이스 예제 만들기 (0) | 2022.09.26 |