LinkedHashMap을 이용한 학교 구성원 관리 시스템 프로젝트를 하고자한다.
요구사항
학교 구성원 정보를 관리하는 시스템을 구축하고자 한다.
구성원 정보는 다음과 같다
학생(Student) 정보는 전화번호 tel, 이름 name, 주소 address, 학번 stuId으로 구성된다.
교사(Teacher) 정보는 전화번호 tel, 이름 name, 주소 address, 과목 subject로 구성된다.
직원(Employee) 정보는 전화번호 tel, 이름 name, 주소 address, 부서 department로 구성된다.
시스템 주요 기능은 다음과 같다.
설계 : UML Class Diagram으로 도출
package model.vo; //vo : Value Object
public abstract class Member {
//직접 객체화 되지 못하게 하고 자식 클래스에게 멤버(인스턴스 변수, 메소드)를 물려주고, 계층 구조 형성을 통해 다형성 적용환경을 제공
private String tel;
private String name;
private String address;
public Member(String tel, String name, String address) {
super();
this.tel = tel;
this.name = name;
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "tel=" + tel + ", name=" + name + ", address=" + address + ", ";
}
}
StarUML에서 볼 수 있는것처럼 나머지 세개의 클래스들에게 동일하게 적용되는 tel, name, address 인스턴스 변수를 생성하고 생성자, getter, setter를 작성하고 출력문에 필요한 toString() 메소드를 오버라이딩해주었다.
package model.vo;
public class Student extends Member{
private String stuId;
public Student(String tel, String name, String address, String stuId) {
super(tel, name, address);
this.stuId = stuId;
}
public String getStuId() {
return stuId;
}
public void setStuId(String stuId) {
this.stuId = stuId;
}
@Override
public String toString() {
return "Student ["+ super.toString() + "stuId=" + stuId + "]";
}
}
package model.vo;
public class Teacher extends Member {
private String subject;
public Teacher(String tel, String name, String address, String subject) {
super(tel, name, address);
this.subject = subject;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
@Override
public String toString() {
return "Teacher [" + super.toString() + "subject=" + subject + "]";
}
}
package model.vo;
public class Employee extends Member {
private String department;
public Employee(String tel, String name, String address, String department) {
super(tel, name, address);
this.department = department;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
@Override
public String toString() {
return "Employee [" + super.toString() + "department =" + department + "]";
}
}
Member클래스를 상속받는 세개의 클래스들을 생성해주었다.
Student 클래스는 stuId를 갖고있고, Teacher 클래스는 subject, Employee 클래스는 department를 갖게끔 각자 고유한 인스턴스 변수를 선언하고, 생성자, getter,setter와 출력에 필요한 toString()을 오버라이딩 했다.
3-1. TestCaseAdd
package test.step1;
import model.service.SchoolService;
import model.vo.Employee;
import model.vo.Student;
import model.vo.Teacher;
public class TestCaseAdd {
public static void main(String[] args) {
SchoolService service = new SchoolService();
service.addMember(new Student("0101231234", "김아무개", "용인", "17"));
service.addMember(new Teacher("0101231235", "박아무개", "수지", "국어"));
service.addMember(new Student("0101231236", "최아무개", "수원", "16"));
service.addMember(new Employee("0101231237", "이아무개", "화성", "재무부"));
service.addMember(new Student("0101231238", "신아무개", "용인", "18"));
service.addMember(new Teacher("0101231239", "권아무개", "용인", "수학"));
// 중복 테스트
// 0101231234 tel 이 중복되어 추가될 수 없습니다
service.addMember(new Student("0101231234", "윤아무개", "잠실", "18"));
System.out.println("***학교 구성원 등록 완료***");
service.printAll();// 6명의 정보가 출력
}
}
먼저 map에 구성원 정보를 추가하는 메소드이다. tel을 중복 확인해서 중복되지 않으면 map에 구성원을 추가하고 중복되면 중복 메시지를 남기고 추가시키지않는다.
3-2. SchoolService
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import model.vo.Member;
public class SchoolService {
private LinkedHashMap<String, Member> map = new LinkedHashMap<>();
public void addMember(Member member) {
if (map.containsKey(member.getTel())) {
System.out.println(member.getTel() + " tel 이 중복되어 추가될 수 없습니다" );
}
else {
map.put(member.getTel(), member);
}
}
우선 LinkedHashMap map 참조변수를 선언한다.
앞으로 이 map에 더하고, 출력하고, 삭제하고, 수정하는 메소드들을 적용할 것이다.
private LinkedHashMap<String, Member> map = new LinkedHashMap<>();
map 변수에 key로는 String 타입의 tel, value는 Member 객체이다.
map.containsKey(member.getTel())
hashmap에 특정 key 존재 여부를 확인하는 메소드이다.
결과가 참이면 true를 거짓이면 false를 반환한다.
이 코드는 'map에 매개변수로 받은 member의 tel이 key값으로 존재한다면'의 제어문이다.
존재한다면 중복되어 등록불가, 존재하지않다면 등록해야하기 때문이다.
map.put(member.getTel(), member);
map에는 put 메소드로 구성원을 넣을 수 있다.
첫번째 자리에는 key를, 두번째 자리에는 value를 넣는다.
0101231234 tel 이 중복되어 추가될 수 없습니다
학교 구성원 등록 완료
Student [tel=0101231234, name=김아무개, address=용인, stuId=17]
Teacher [tel=0101231235, name=박아무개, address=수지, subject=국어]
Student [tel=0101231236, name=최아무개, address=수원, stuId=16]
Employee [tel=0101231237, name=이아무개, address=화성, department =재무부]
Student [tel=0101231238, name=신아무개, address=용인, stuId=18]
Teacher [tel=0101231239, name=권아무개, address=용인, subject=수학]
4-1. TestCaseFind
package test.step2;
import model.service.SchoolService;
import model.vo.Employee;
import model.vo.Member;
import model.vo.Student;
import model.vo.Teacher;
public class TestCaseFind {
public static void main(String[] args) {
SchoolService service = new SchoolService();
service.addMember(new Student("0101231234", "김아무개", "용인", "17"));
service.addMember(new Teacher("0101231235", "박아무개", "수지", "국어"));
service.addMember(new Student("0101231236", "최아무개", "수원", "16"));
service.addMember(new Employee("0101231237", "이아무개", "화성", "재무부"));
service.addMember(new Student("0101231238", "신아무개", "용인", "18"));
service.addMember(new Teacher("0101231239", "권아무개", "용인", "수학"));
service.printAll(); //6명인지 확인
System.out.println("**학교 구성원 등록완료**");
String tel = "0101231237"; //재할당, 존재하는 tel
Member member = service.findMemberByTel(tel);
System.out.println(tel + " tel 구성원 검색 결과:" + member);
//0101231237 tel 구성원 검색 결과 : Employee [tel=0101231237, name=이아무개, address=화성,department=재무부]
tel = "0101231230"; // 리스트에 존재하지 않는 (등록되지않은) tel
member = service.findMemberByTel(tel);
System.out.println(tel + " tel 구성원 검색 결과:" + member);
//0101231230 tel 구성원 검색 결과 : null
}
}
마찬가지로 member 구성원을 더하고, 구성원을 검색해서 결과를 출력하는 메소드이다.
4-2. SchoolService
public Member findMemberByTel(String tel) {
return map.get(tel);
}
TestCaseFind 클래스에서 findMemberByTel함수를 호출할 때 String 데이터 타입의 tel을 매개변수로 넣어주기때문에 key값에 해당하는 value를 반환(return)할 수 있도록 한 코드이다.
Student [tel=0101231234, name=김아무개, address=용인, stuId=17]
Teacher [tel=0101231235, name=박아무개, address=수지, subject=국어]
Student [tel=0101231236, name=최아무개, address=수원, stuId=16]
Employee [tel=0101231237, name=이아무개, address=화성, department =재무부]
Student [tel=0101231238, name=신아무개, address=용인, stuId=18]
Teacher [tel=0101231239, name=권아무개, address=용인, subject=수학]
학교 구성원 등록완료
0101231237 tel 구성원 검색 결과:Employee [tel=0101231237, name=이아무개, address=화성, department =재무부]
0101231230 tel 구성원 검색 결과:null
5-1. TestCaseDelete
package test.step3;
import model.service.SchoolService;
import model.vo.Employee;
import model.vo.Student;
import model.vo.Teacher;
public class TestCaseDelete {
public static void main(String[] args) {
SchoolService service = new SchoolService();
service.addMember(new Student("0101231234", "김아무개", "용인", "17"));
service.addMember(new Teacher("0101231235", "박아무개", "수지", "국어"));
service.addMember(new Student("0101231236", "최아무개", "수원", "16"));
service.addMember(new Employee("0101231237", "이아무개", "화성", "재무부"));
service.addMember(new Student("0101231238", "신아무개", "용인", "18"));
service.addMember(new Teacher("0101231239", "권아무개", "용인", "수학"));
service.printAll(); //6명인지 확인
System.out.println("**학교 구성원 등록완료**");
System.out.println();
String tel = "0101231230";//존재하지않는 tel
service.deleteMemoryByTel(tel);
//0101231230 tel에 해당하는 구성원 정보가 없어서 삭제 불가합니다
System.out.println();
tel="0101231238"; //존재하는 tel : 신아무개님 번호입니다.
service.deleteMemoryByTel(tel);
//0101231238 tel에 해당하는 구성원 정보가 삭제되었습니다
System.out.println();
System.out.println("전체 구성원 리스트 출력");
service.printAll(); //삭제되었으므로 5명이 출력된다.
System.out.println("**학교 구성원 삭제 테스트 완료**");
}
}
member를 더해주고 tel을 선언해 해당하는 member를 삭제하는 코드이다.
5-2. SchoolService
public void deleteMemoryByTel(String tel) {
if (map.containsKey(tel)) {
map.remove(tel);
System.out.println(tel + "tel에 해당하는 구성원 정보가 삭제되었습니다");
}
else {
System.out.println(tel + " tel에 해당하는 구성원 정보가 없어서 삭제 불가합니다");
}
}
key인 tel을 매개변수로 받아 map에 존재하면 삭제하는 코드이다.
map.remove(tel);
remove 메소드로 키에 해당하는 멤버를 지울 수 있다.
6-1. TestCaseUpdate
package test.step4;
import model.service.SchoolService;
import model.vo.Employee;
import model.vo.Student;
import model.vo.Teacher;
public class TestCaseUpdate{
public static void main(String[] args) {
SchoolService service = new SchoolService();
service.addMember(new Student("0101231234", "김아무개", "용인", "17"));
service.addMember(new Teacher("0101231235", "박아무개", "수지", "국어"));
service.addMember(new Student("0101231236", "최아무개", "수원", "16"));
service.addMember(new Employee("0101231237", "이아무개", "화성", "재무부"));
service.addMember(new Student("0101231238", "신아무개", "용인", "18"));
service.addMember(new Teacher("0101231239", "권아무개", "용인", "수학"));
service.printAll(); //6명인지 확인
System.out.println("**학교 구성원 등록완료**");
service.updateMember(new Teacher("0101231230", "박아무개", "동탄", "자바"));
//0101231230 tel에 해당하는 구성원 정보가 없어 수정불가합니다.
service.updateMember(new Employee("0101231235","박아무개","성남", "기획"));
//0101231235 tel에 해당하는 구성원 정보에 해당하는 구성원 정보가 수정되었습니다.
System.out.println("**학교 구성원 정보 수정**");
service.printAll();
System.out.println("**학교 구성원 수정 테스트 완료**");
}
}
6-2. SchoolService
public void updateMember(Member member) {
if (map.containsKey(member.getTel())) {
map.put(member.getTel(), member);
System.out.println(member.getTel() + " tel에 해당하는 구성원 정보에 해당하는 구성원 정보가 수정되었습니다");
}
else {
System.out.println("tel에 해당하는 구성원 정보가 없어 수정불가합니다.");
}
}
put메소드로 덮어쓰기와 같이 해당하는 멤버를 변경 할 수 있다.