기본적인 구현 방식 및 전체 구조 설명
main()에서 while문과 switch문을 사용하여 user가 선택한 메뉴의 번호(option)에 따라서 해당 메뉴의 메소드를 실행한다.
연락처 프로그램을 끝내면 juso.txt 파일에 등록된 연락처를 출력한다.
메인 메소드에서는 메인 메뉴와 관련된 실행문을 호출하여 실행한다.
print_menu: 메인 메뉴, 상세메뉴를 출력
veiw_juso: 저장된 just.txt 파일에서 연락처를 읽어서 화면에 출력
add_juso: 새로 입력하는 연락처를 배열에 추가
delete_juso: 사용자가 선택한 옵션에 따라 연락처를 배열에서 삭제
checkData : 배열리스트에 데이터가 있는지 확인
writeMyData: 사용자가 등록한 연락처를 juso.txt 파일에 저장
loadFileData: 저장된 just.txt파일에서 읽은 연락처를 등록
각 메소드 및 클래스 별 (코드) 내용 설명
class MyData{
private String name;
private int age;
private String phoneNum;
public MyData(String name, int age, String phoneNum) {
this.name = name;
this.age = age;
this.phoneNum = phoneNum;
}
public String getName() { return this.name; }
public int getAge() { return this.age; }
public String getPhoneNum() { return this.phoneNum; }
public String toString() {
return name + "(" + age + "세) : " + phoneNum;
}
}
MyData는 콘솔에서 사용자가 입력한 연락처 데이터를 저장할 객체이다. 사용자가 입력하는 이름과 나이, 전화번호의 값을 가져오는 getter를 정의하여 콘솔에 데이터를 출력할 때 사용한다. 또한 연락처 목록을 콘솔에 출력할 때 사용할 이름과 나이, 전화번호를 한 번에 보여주는 toString 매소드를 정의하였다.
public static void main(String[] args) {
finalproject program = new finalproject();
Scanner in = new Scanner(system.in);
System.out.print("[연락처 관리 프로그램]\n\n");
program.print_menu(program.mainMenu);
program.loadFileData();
while (true) {
System.out.print("메뉴를 선택하세요: ");
while (!in.hasNextInt()) {
in.next();
System.out.print("\n숫자를 입력해주세요: ");
}
int option = in.nextInt();
if (option == 4) { break; }
switch (option) {
case 1:
program.view_juso();
program.print_menu(program.mainMenu);
break;
case 2:
program.add_juso();
program.print_menu(program.mainMenu);
break;
case 3:
program.delete_juso();
program.print_menu(program.mainMenu);
break;
default:
System.out.print("잘못된 메뉴입니다.");
break;
}
}
program.writeMyData();
}
finalproject 클래스 내부에 main()메소드이다.
메인 메소드에서 while문과 switch문을 사용하여 메뉴를 출력하고 사용자가 프로그램을 끝내기 전까지 입력받은 메뉴의 번호(option)에 해당하는 실행문을 실행한다.
메뉴를 처음 출력하고 사용자가 입력한 option이 숫자가 아닌 경우에는 숫자를 입력할 때까지 whlie문을 반복한다.
사용자가 입력한 option이 4일 경우에는 바로 프로그램을 종료하고 등록된 연락처를 juso.txt 파일에 입력하는 writeMyData() 메소드를 실행한다.
사용자가 입력한 option이 메뉴에 해당되는 번호가 아닌 경우에 “잘못된 메뉴입니다.”를 출력한 다음 mainMenu를 다시 출력한다.
public class finalproject {
Scanner in = new Scanner(system.in);
boolean mainMenu = true;
ArrayList<MyData> data = new ArrayList<MyData>();
public void print_menu(boolean mainMenu) {
// menu를 출력합니다.
if (mainMenu) {
System.out.println("\n=======Main Menu=======");
System.out.print("\n1) 연락처 출력 \n2) 연락처 등록 \n3) 연락처 삭제 \n4) 끝내기\n\n");
System.out.println("=======================\n");
} else {
System.out.println("\n=======Delete Menu======");
System.out.println("\n1) 순번 삭제 \n2) 이름 삭제 \n3) 번호 삭제 \n4) 메인메뉴로 이동\n");
System.out.println("=======================\n");
}
}
boolean타입의 mainMenu 변수는 print_menu() 메소드에 전달할 인자변수로 print_menu() 메소드에 전달된 변수가 mainMenu인 경우에는 메인 메뉴를 출력하고 아닌 경우(!mainMenu)에는 삭제 메뉴의 상세메뉴를 출력하기 위해 정의한 변수이다.
자바 라이브러리에서 제공하는 ArrayList를 사용하여 콘솔에서 사용자가 입력하는 정보를 저장하는 객체인 MyData 타입의 변수 그릇을 만들어 연락처를 추가하고 삭제하거나 등록한 MyData 타입의 데이터들을 확인하는데에 사용하고자 한다.
print_menu()메서드는 전달받은 인자 변수에 따라서 콘솔에 메뉴를 출력합니다.
public String toString() {
String ret = "";
for (int i = 0; i < data.size(); i++) {
int index = i + 1;
ret += "[" + index + "] " + data.get(i).toString() + "\n";
}
return ret;
}
연락처 프로그램이 종료되고 파일에 연락처 목록을 출력하기 위해 정의한 메소드이다.
public void writeMyData() {
File file = new File("juso.txt");
FileWriter fw;
try {
fw = new FileWriter(file);
fw.write(toString());
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void loadFileData() throws IOException {
List<String> readData = Files.readAllLines(Paths.get("juso.txt"));
StringTokenizer st;
String[] arr;
for (int i = 0; i < readData.size(); i++) {
st = new StringTokenizer(
readData.get(i).toString().replace("[", "").replace("]", "").replace("(", " ").replace(")", ""), " ");
int index = 0;
arr = new String[st.countTokens()];
while (st.hasMoreTokens()) {
arr[index] = st.nextToken();
index++;
}
String name = arr[1];
int age = Integer.parseInt(arr[2]);
String phoneNum = arr[3];
data.add(new MyData(name, age, phoneNum));
}
}
writeMyData()는 프로그램에서 사용자가 종료하기 전까지 등록한 연락처 데이터를 just.txt 파일에 입력하는 메소드이다.
loadFileData()는 just.txt 파일에서 읽어온 데이터를 StringTokenizer를 사용하여 단어 별로 분리하면 순번과 이름, 나이, 전화번호 순으로 정렬된다. 정렬된 데이터를 String 타입의 배열에 담아서 각각 정렬된 데이터를 저장할 MyData를 실체화 한 다음 실체화된 MyData타입을 data 배열 리스트에 추가한다. 이렇게 해서 just.txt 파일에서 읽어온 데이터를 추가한다.
public void view_juso() {
// 등록된 데이터가 있는 경우에 연락처 목록을 출력합니다.
checkData();
for (int i = 0; i < data.size(); i++) {
System.out.printf("[%d] %s\n", i + 1,
data.get(i).toString());
}
}
사용자가 메인메뉴에서 연락처 출력 option을 입력할 시 현재까지 data 배열리스트에 등록된 데이터가 있는 동안에 MyData 클래스에서 정의한 toString메소드를 호출하여 콘솔에 연락처 목록을 출력한다.
public void add_juso() {
// 연락처를 등록합니다.
System.out.print("\n이름 입력: ");
String name = in.next();
System.out.print("나이 입력: ");
while (!in.hasNextInt()) {
in.next();
System.out.print("\n숫자를 입력해주세요: ");
}
int age = in.nextInt();
System.out.print("번호 입력: ");
String phoneNum = in.next();
data.add(new MyData(name, age, phoneNum));
}
정의한 순서대로 콘솔에 이름과 나이, 번호를 입력하면 해당 데이터를 저장할 MyData를 실체화 한 다음 실체화된 MyData 타입을 data 배열 리스트에 추가한다. 여기서 나이를 입력하는 경우 반드시 숫자만 입력할 수 있도록 숫자가 아닌 경우에는 반복문을 실행한다.
private boolean checkData() {
// data가 입력됐는지 여부를 확인합니다.
if (data.size() <= 0) {
System.out.println("등록된 연락처가 없습니다. \n메인 메뉴로 돌아갑니다. \n");
return false;
}
return true;
}
배열리스트가 비어있는 경우는 연락처가 등록되지 않은 경우이다. 따라서 배열리스트의 사이즈가 0인 경우에는 등록된 연락처가 없다는 메시지를 콘솔에 출력하고 false를 반환한다. 그렇지 않는 경우 true를 반환한다.
public void delete_juso() {
while (checkData()) {
print_menu(!mainMenu);
System.out.print("메뉴를 선택하세요: ");
int option = in.nextInt();
if (option == 4) { break;}
switch (option) {
case 1:
System.out.print("삭제할 연락처의 순번을 입력해주세요: ");
int index = in.nextInt();
if (index > data.size() || index <= 0) {
System.out.printf("없는 순번(%d)을 입력하였습니다.\n", index);
} else {
data.remove(index - 1);
System.out.printf("입력한 (%d)순번의 연락처를 삭제하였습니다.\n\n", index);
}
break;
case 2:
System.out.print("삭제할 연락처의 이름을 입력해주세요: ");
String name = in.next();
int count = 0;
for (int i = 0; i < data.size(); i++) {
if (name.equals(data.get(i).getName())) {
data.remove(i);
System.out.printf("입력한 (%s)이름의 연락처를 삭제하였습니다.\n\n", name);
count++;
}
}
if (count == 0) {
System.out.printf("해당 이름(%s)의 연락처는 없습니다. \n\n", name);
}
break;
case 3:
System.out.print("삭제할 연락처의 번호를 입력해주세요: ");
String phoneNum = in.next();
count = 0;
for (int i = 0; i < data.size(); i++) {
if (phoneNum.equals(data.get(i).getPhoneNum())) {
data.remove(i);
System.out.printf("입력한 (%s)번호의 연락처를 삭제하였습니다.\n\n", phoneNum);
count++;
}
}
if (count == 0) {
System.out.printf("해당 번호(%s)의 연락처는 없습니다.\n\n", phoneNum);
}
break;
default:
System.out.print("잘못된 세부 메뉴입니다.\n");
break;
}
}
}
delete_juso()는 상세메뉴를 출력하고 출력된 상세메뉴 option을 입력 할 시에 해당된 메뉴에 맞는 행위를 switch문에 정의하여 실행하도록 한다. 메인 메소드에서 메인 메뉴를 출력하는 등의 로직과 유사하다.
다만 상세메뉴를 실행하는 조건이 배열 리스트에 데이터가 있어야 한다. 배열리스트에 삭제할 수 있는 데이터가 있어야 삭제 상세메뉴를 콘솔에 출력한다.
순번을 삭제하는 경우 사용자가 콘솔에서 삭제하고자 하는 연락처의 순번을 입력했을 때 해당 순번이 존재하지 않는 경우(배열리스트 사이즈보다 큰 수의 순번인 경우, 입력한 순번이 음수인 경우)에 없는 순번을 입력하였다는 메세지를 출력하고 다시 상세 메뉴를 출력한다. 배열리스트에 존재하는 순번을 입력한 경우 바로 배열리스트에서 해당 데이터를 삭제한다.
이름을 입력하여 삭제하는 경우 사용자가 입력한 데이터가 배열리스트에 존재하는 지 배열에 있는 모든 데이터를 for문을 통해 확인한 다음 해당되는 데이터가 존재하는 경우 삭제한다. 그렇지 않은 경우는 입력된 데이터가 배열리스트에 있는 데이터 중 동일한 데이터가 아예 없는 경우이다. 이때 int타입의 count변수를 사용하여 count가 0인 경우에 해당되는 연락처가 없음을 출력한다.
연락처 번호를 삭제하는 경우는 이름을 삭제하는 경우와 완전하게 유사합니다. phoneNum 변수를 String타입으로 정의하였기 때문이다.
프로그램 실행결과(화면 캡쳐)
연락처 프로그램 종료 후 프로그램을 다시 실행한 뒤 연락처를 출력하면 juso.txt에 데이터가 있는 경우 연락처 목록을 출력
소스 코드: https://github.com/kimgoat/contect_management/blob/main/src/contect_management/Main.java
'🗂️ Project Review' 카테고리의 다른 글
[React] Github Profile Finder (1) | 2024.01.11 |
---|---|
[JavaScript] 사칙 연산 퀴즈 (0) | 2023.12.26 |
[JavaScript] 줄임말 프로그램 (1) | 2023.12.25 |
[HTML&CSS] 네이버 메인 페이지 UI 일부 구현해보기 (0) | 2023.12.24 |
[Java] Checksum Calculator (체크섬 계산기) (1) | 2023.12.23 |