java/java.util & java.text

[java.util] 7. 학생 관리 프로그램 (Set,List,Map 활용)

jeri 2024. 6. 28. 01:27
반응형

01. [VO] Student.java

  • Value Object 클래스
  • 값을 저장할 목적의 객체를 만들기 위한 클래스
package xyz.itwill.util;

//hashcode() & equals() 메소드는 중복된 값들이 따로 저장되지 않았으면 좋겠을 때 오버라이드 선언하여 사용함!!!!
//하지만 Set객체를 쓰지 않는 이상 이렇게 오버라이드 선언 잘 안함
//데이터베이스를 이용할 것이니 이렇게 사용하지 않음
//데이터베이스를 이용하면 중복된 값이 저장안되게끔 할 수 있음

//학생정보(학번,이름)를 저장하기 위한 클래스 - VO(Value Object) 클래스
// => 객체의 컬럼값을 비교하기 위한 기능을 제공받기 위해 Comparable 인터페이스를 상속받아 작성
public class Student implements Comparable<Student> {
	//필드
	private int num;
	private String name;
	//생성자
	public Student() {	}
	public Student(int num, String name) { super(); this.num = num; this.name = name; }
	//Getter & Setter
	public int getNum() {return num;}
	public void setNum(int num) {this.num = num;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}

	//Object 클래스의 toString() 메소드를 오버라이드 선언
	// => VO 클래스에 저장된 필드값을 반환받아 확인하기 위해 선언
	@Override
	public String toString() {
		return "학번 = "+num+", 이름 = "+name;
	}

	//Object 클래스의 hashCode() 메소드를 오버라이드 선언
	// => 객체의 메모리 주소 대신 VO 클래스의 필드값을 반환
	@Override
	public int hashCode() {
		return num;
	}

	//Object 클래스의 equals() 메소드를 오버라이드 선언
	// => VO 클래스에 저장된 필드값을 비교하여 결과를 반환하기 위해 사용
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Student) {
			//매개변수로 전달받은 객체를 명시적 객체 형변환하여 참조변수에 저장
			Student student=(Student)obj;

			//메소드의 객체(this)와 매개변수로 전달받은 객체(obj)의 필드값을 비교하여 논리값 반환
			// => 학번를 비교하여 같은 경우 [true] 반환
			if(num==student.num) return true;
		}
		//비교가 불가능하거나 학번이 다른 경우 [false] 반환
		return false;
	}


  	//🍑추가
	//객체의 컬럼값을 매개변수로 전달받은 객체의 컬럼값과 비교하여 결과를 반환하는 메소드
	// => 객체의 컬럼값이 큰 경우 양수 반환하고, 매개변수로 전달받은 객체의 컬럼값이 큰 경우 음수 반환되며, 같은 경우 0을 반환하도록 명령 작성
	// => 오름차순 또는 내림차순 정렬을 위한 비교값 설정 
	@Override
	public int compareTo(Student o) {
		//return /*this.*/num-o.num;//학번을 비교하여 오름차순 정렬되도록 설정
		//return o.num-/*this.*/num;//학번을 비교하여 내림차순 정렬되도록 설정
		//return name.compareTo(o.name);//이름을 비교하여 오름차순 정렬되도록 설정
		return o.name.compareTo(name);//이름을 비교하여 내림차순 정렬되도록 설정
	}
}

02. [BO] StudentManager.java

  • Business Object 클래스 / Manager 클래스
  • 일을 하는 객체를 만들어주는 클래스
  • VO클래스를 이용해 저장매체에 필요한 정보 저장 & 관리(저장,변경,삭제,검색 - CRUD)하는 클래스
  • Manager 클래스를 통해 필요한 정보 관리 가능해짐!

📌 알고 넘어가기

  • 아래의 작성된 BO클래스의 저장매체는 ArrayList로 만들었음
  • ArrayList를 저장매체로 이용한 것은 메모리(ram)를 이용하는 휘발성
  • 실제 저장매체로 쓰기에는 비권장, 반영구적 저장을 위해서는 file, DataBase를 이용함
  • 아래의 메소드를 자세히 알 필요는 없지만, 형식은 이렇게 흘러감
package xyz.itwill.util;
import java.util.ArrayList;
import java.util.List;


//학생정보를 관리(저장,변경,삭제,검색 - CRUD)하는 기능을 제공하는 클래스
//=>BO(Business Object) 클래스 - Manager 클래스
public class StudentManager {

	//다수의 학생정보(Student객체)를 저장하기 위한 콜렉션 필드 - 저장매체
  	//ArrayList객체 내 Student정보 여러개 저장 가능해짐 - 콜렉션필드
	private List<Student> studentList = new ArrayList<Student>();

  	//Getter메소드 : 콜렉션 필드에 저장된 모든 학생정보를 반환하는 메소드
	public List<Student>getStudentList() {
		return studentList;
  }


	//🌻클래스 내 모든 메소드에서 공통적으로 사용하기 위한 메소드
  	//getStudentIndex(int num)메소드
	//=>학번을 전달받아 콜렉션 필드에 저장된 요소의 학번과 비교하여 같은 요소의 첨자를 반환하는 메소드
	private int getStudentIndex(int num) {
		int index = -1; //초기값으로 존재하지 않는 첨자를 저장

		//콜렉션 필드에 저장된 모든 요소(Student객체)의 일괄처리를 위한 반복문
    	//=>ArrayList의 일괄처리방법 - for문 활용
		for(int i = 0; i<studentList.size(); i++) {
			// => studentList.get(0) : studentList에 저장된 0번째 요소(객체) 반환 - 반환자료형: Student
      		// => studentList.get(0).getNum() : Student객체가 가진 필드 중 num(학번)의 Getter메소드를 호출하여 num(학번) 반환받음 - 반환자료형: int
			if(studentList.get(i).getNum() == num) { //콜렉션 필드(studentList객체)에 저장된 요소(Student객체)의 학번과 매개변수로 전달받은 학번이 같은 경우
				index = i; //같다면, 해당하는 요소의 첨자를 저장
				break;
			}
		}
		return index; //요소의 첨자 반환 - 콜렉션 필드에서 요소가 미검색된 경우 -1 반환
	}

	//1.
  	//addStudent(Student student) - return값: boolean
	//학생정보를 전달받아 콜렉션 필드의 요소로 추가하고 처리 결과를 반환하는 메소드
	//=> false 반환 : 콜렉션 필드의 요소 추가 실패
  	//=> true 반환 : 콜렉션 필드의 요소 추가 성공
	//=> 전달받은 학생정보의 학번이 이미 콜렉션 필드에 저장된 요소의 학번과 같은 경우 추가되지 않도록 작성 - 중복 저장 방지
	public boolean addStudent(Student student) {
		//콜렉션 필드에 이미 저장된 학번의 학생정보인 경우
		if(getStudentIndex(student.getNum()) != -1) {
			return false;
		}
		studentList.add(student); //List 객체에 요소를 추가하는 메소드 호출
		return true;
	}

  	//2.
  	//getStudent(int num) - return값: Student
	//학번을 전달받아 콜렉션 필드의 요소를 검색하여 학생정보를 반환하는 메소드
	public Student getStudent(int num) {
		int index = getStudentIndex(num);
		//콜렉션 필드에 저장된 학번의 학생정보가 아닌 경우
		if(index == -1) {
			return null; //검색된 학생정보가 없는 경우 null 반환
		}
		return studentList.get(index); //List객체에서 첨자위치의 요소를 반환하는 메소드 호출
	}

	//3.
  	//modifyStudent(Student student) - return값: boolean
	//학생정보를 전달받아 콜렉션 필드의 요소로 변경하고 처리 결과를 반환하는 메소드
	//=> false 반환 : 콜렉션 필드의 요소 변경 실패
  	//=> true 반환 : 콜렉션 필드의 요소 변경 성공
	//=> 전달받은 학생정보의 학번이 콜렉션 필드에 저장된 요소의 학번이 아닌 경우 변경 실패
	public boolean modifyStudent(Student student) {
		int index = getStudentIndex(student.getNum());
		//콜렉션 필드에 저장된 학번의 학생정보가 아닌 경우
		if(index == -1) {
			return false;
		}
		studentList.set(index, student); //List 객체에서 첨자위치의 요소를 변경하는 메소드 호출
		return true;
	}

	//4.
  	//removeStudent(int num) - return값: boolean
	//학번을 전달받아 콜렉션 필드의 요소로 삭제하고 처리 결과를 반환하는 메소드
	//=> false 반환 : 콜렉션 필드의 요소 삭제 실패
  	//=> true 반환 : 콜렉션 필드의 요소 삭제 성공
	//=> 전달받은 학번이 콜렉션 필드에 저장된 요소의 학번이 아닌 경우 삭제 실패
	public boolean removeStudent(int num) {
		int index = getStudentIndex(num);
		//콜렉션 필드에 저장된 학번의 학생정보가 아닌 경우
		if(index == -1) {
			return false;
		}
		studentList.remove(index); //List 객체에서 첨자위치의 요소를 삭제하는 메소드 호출
		return true;
	}

}

 

 

 

 

 

03. StudentSetApp.java

package xyz.itwill.util;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class StudentSetApp {
	public static void main(String[] args) {

		//Set객체에 student객체 저장
		Set<Student> studentSet = new HashSet<Student>();

		//studentSet.add(Student e)
		//studentSet.add(new Student());
  
		//add
		studentSet.add(new Student(1000,"홍길동"));
		studentSet.add(new Student(2000,"임꺽정"));
		studentSet.add(new Student(3000,"전우치"));

		//Student 필드값은 동일하나 메모리주소가 다르므로 다른객체로 인식해 Set객체에 저장됨
		studentSet.add(new Student(1000,"홍길동"));
		System.out.println("요소의 갯수 = "+studentSet.size()); //요소의 갯수 = 4

		//문제점
		// => Set 객체에 동일한 값이 저장된 서로 다른 Student 객체 2개가 있는 것!
		// => 두 객체는 주소값이 다르게 저장된다.
		// => 하지만 실질적으로 학번과 이름이 같으므로 같은사람인데, 다른객체로 생성되어 다른사람 취급하네?

		//해결법
		// => hashCode() 메소드와 equals() 메소드를 오버라이드 선언하여 동일한 값이 저장된
		// => 객체가 Set 객체의 요소로 저장하지 않도록 설정 가능
		// => 매개변수로 전달받은 객체를 hashCode() 메소드로 기존 요소의 HashCode와 비교하여 
		// => 같은 경우 equals() 메소드로 필드값을 비교해 같으면 Set 객체에 추가되지 않도록 동작
		// => HashCode가 다르거나 비교 필드값이 다르면 Set 객체에 요소가 추가되어 저장
		//studentSet.add(new Student(1000,"홍길동")); //학번이 같은 학생정보 저장 불가능
		System.out.println("요소의 갯수 = "+studentSet.size()); //요소의 갯수 = 3

		// => HashCode가 다르거나 비교 필드값이 다르면 Set 객체에 요소가 추가되어 저장
		studentSet.add(new Student(4000, "홍길동"));
		System.out.println("요소의 갯수 = "+studentSet.size());ㅜ//요소의 갯수 = 4

		//일괄처리를 위한 반복지시자 Iterator객체 사용
		Iterator<Student> iterator = studentSet.iterator();
		while (iterator.hasNext()) {
			//객체를 반환받아 출력할 경우 Student.toString() 메소드 자동 호출
			System.out.println(iterator.next());
		}
		//학번 = 2000, 이름 = 임꺽정
		//학번 = 4000, 이름 = 홍길동
		//학번 = 1000, 이름 = 홍길동
		//학번 = 3000, 이름 = 전우치

	}
}

04. StudentManagerApp.java

  • 학생관리프로그램 - CRUD기능사용
package xyz.itwill.util;
import java.util.List;
import java.util.Collections;

//학생관리프로그램
public class StudentManagerApp {
	public static void main(String[] args) {

		//1.
		StudentManager manager = new StudentManager();

		//2.
		//학생정보를 전달하여 저장매체(콜렉션필드, 여기서는 ArrayList객체)에 저장하는 메소드 호출
		manager.addStudent(new Student(1000, "홍길동")); // 학생 1명이 ArrayList에 저장됨
		manager.addStudent(new Student(2000, "임꺽정")); // 학생 1명이 ArrayList에 저장됨
		manager.addStudent(new Student(3000, "전우치")); // 학생 1명이 ArrayList에 저장됨
		manager.addStudent(new Student(4000, "일지매")); // 학생 1명이 ArrayList에 저장됨
    	System.out.println("StudentList에 저장된 Student객체 개수 = "+manager.getStudentList().size());
    	//StudentList에 저장된 Student객체 개수 = 4

		//3.
		// 상태변수를 이용해 출력도 가능 - 잘 사용하지 않지만..
		boolean result1 = manager.addStudent(new Student(5000, "장길산"));
        if(result1) {
			System.out.println("[메세지]학생정보를 성공적으로 저장 하였습니다.");
		} else {
			System.out.println("[메세지]이미 저장된 학번의 학생정보이므로 저장되지 않습니다.");
		}
		//[메세지]학생정보를 성공적으로 저장 하였습니다.
		boolean result2 = manager.addStudent(new Student(1000, "장길산"));
        if(result2) {
			System.out.println("[메세지]학생정보를 성공적으로 저장 하였습니다.");
		} else {
			System.out.println("[메세지]이미 저장된 학번의 학생정보이므로 저장되지 않습니다.");
		}
		//[메세지]이미 저장된 학번의 학생정보이므로 저장되지 않습니다.


		//4.
		//학번이 [2000]인 학생정보를 저장매체에서 검색하여 출력
		Student searchStudent = manager.getStudent(2000);
		if(searchStudent == null) { //검색된 학생정보가 없는 경우
			System.out.println("[메세지]해당 학번의 학생정보를 찾을 수 없습니다.");
		}else {
			System.out.println(searchStudent);
		}
		//학번 = 2000, 이름 = 임꺽정

		//5.
		//저장매체에서 학번이 [2000]인 학생의 이름을 [임걱정]으로 변경
		searchStudent.setName("임걱정");
    	//manager.getStudent(2000).setName("임걱정");
		manager.modifyStudent(searchStudent);
		System.out.println("[메세지]학생정보를 성공적으로 변경 하였습니다.");
    	//[메세지]학생정보를 성공적으로 변경 하였습니다.

    	//6.
		//학번이 [4000]인 학생정보를 저장매체에서 삭제
		if(manager.removeStudent(4000)) { //삭제된 학생정보가 있는 경우
			System.out.println("[메세지]학생정보를 성공적으로 삭제 하였습니다.");
		} else {
			System.out.println("[메세지]해당 학번의 학생정보를 찾을 수 없습니다.");
		}
    	//[메세지]학생정보를 성공적으로 삭제 하였습니다.

    	//7.
		//저장매체에 저장된 모든 학생정보를 반환하는 메소드 호출
		List<Student> students = manager.getStudentList();
		for(Student student: students) {
			//Student.toString()메소드 자동 호출 - 필드값을 반환받아 출력
			System.out.println(student); //순서있음!
		}
    	//학번 = 1000, 이름 = 홍길동
		//학번 = 2000, 이름 = 임걱정
		//학번 = 3000, 이름 = 전우치
		//학번 = 5000, 이름 = 장길산

		//8.
		//List객체에 저장된 요소를 정렬하여 출력
    	// => Collections.sort(List<T> list) 메소드의 매개변수에 전달되는 List객체는
    	//요소값을 비교하기 위한 기능의 compareTo() 메소드가 오버라이드 선언되지 않은 경우 에러 발생
    	// => List객체의 studentList객체 안에는 정렬할 수 있는 기준이 없어서 error
    	// => compareTo() 메소드 오버라이드 선언해주기
  		// => step1. compareTo() 메소드를 가진 Comparable<T>인터페이스 상속받기
  		// => step2. <T>제네릭 : <Student>으로 만들기
  		// => step3. compareTo() 오버라이드 선언하기
		Collections.sort(students);
        for(Student student: students) {
			//Student.toString()메소드 자동 호출 - 필드값을 반환받아 출력
			System.out.println(student);
		}
		//학번 = 2000, 이름 = 임걱정
		//학번 = 5000, 이름 = 장길산
		//학번 = 3000, 이름 = 전우치
		//학번 = 1000, 이름 = 홍길동

	}
}

05. StudentMapApp.java

  • List + Map 함께 사용한 학생 관리 프로그램
  • Map 안에 List 넣어 이용함
package xyz.itwill.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class StudentMapApp {
	public static void main(String[] args) {

  		//1.
    	//ArrayList객체 생성
		List<Student> studentListOne = new ArrayList<Student>();
		studentListOne.add(new Student(1000, "홍길동"));
		studentListOne.add(new Student(2000, "임꺽정"));
		studentListOne.add(new Student(3000, "전우치"));
		studentListOne.add(new Student(4000, "일지매"));
		studentListOne.add(new Student(5000, "장길산"));

		//2.
    	//ArrayList객체 생성
		List<Student> studentListTwo = new ArrayList<Student>();
		studentListTwo.add(new Student(1000, "유재석"));
		studentListTwo.add(new Student(2000, "강호동"));
		studentListTwo.add(new Student(3000, "신동엽"));
		studentListTwo.add(new Student(4000, "김용만"));

    	//3.
    	//HashMap객체의 key값 : Integer
    	//HashMap객체의 Value값 : List<Student>
		Map<Integer, List<Student>> studentMap = new HashMap<Integer, List<Student>>();

    	//4.
    	//Map 메소드 이용해 studentMap에 List<Student>객체저장
		studentMap.put(1, studentListOne);
		studentMap.put(2, studentListTwo);

    	//5-1.
    	//Set객체로 반환받은 Key값들 + 향상된for문 이용
		for(Integer ban:studentMap.keySet()) {
			System.out.println(ban + "반의 학생 정보 >> ");
			List<Student> studentList = studentMap.get(ban);
			for(Student student:studentList) {
				System.out.println(student);
			}
			System.out.println("===================================");
		}

    	//5-2.
    	//Set객체로 반환받은 Key값들 + for문 이용
		for(Integer ban:studentMap.keySet()) {
			System.out.println(ban + "반의 학생 정보 >> ");
			List<Student> studentList = studentMap.get(ban);
            for(int i = 0; i < studentList.size(); i++) {
				System.out.println(studentList.get(i));
			}
			System.out.println("===================================");
		}



	}
}
//1반의 학생 정보 >>
//학번 = 1000, 이름 = 홍길동
//학번 = 2000, 이름 = 임꺽정
//학번 = 3000, 이름 = 전우치
//학번 = 4000, 이름 = 일지매
//학번 = 5000, 이름 = 장길산
//===================================
//2반의 학생 정보 >>
//학번 = 1000, 이름 = 유재석
//학번 = 2000, 이름 = 강호동
//학번 = 3000, 이름 = 신동엽
//학번 = 4000, 이름 = 김용만
//===================================
반응형