첫 개인 프로젝트라 문법 이해와 학습을 위해 코드마다 메모처럼 주석처리를 했다. 나중에 익숙해진 문법들부터 차차 주석 제거 예정이다
⭐ 여기서부터 헷갈리고 막히기 시작해서 지금까지 제대로 이해하지 못 하고 두루뭉술하게 넘어갔던 부분들이 꽤나 많아서 그런가 싶어서 김영한 인강 들으며 자바 공부를 기초부터 다시 하고 있다
요구사항 체크리스트 ⬜✅ :
Calcualtor 클래스에서 저장된 연산 결과들 중 가장 먼저 저장된 데이터를 삭제하는 기능을 가진 메서드를 구현한 후 App 클래스의 main 메서드에 삭제 메서드가 활용될 수 있도록 수정
✅ 키워드 : 컬렉션
✅ 컬렉션에서 '값을 넣고 제거하는 방법을 이해하는 것'이 중요!
우선, 연산 과정에서 언제든 exit 를 입력하면 계산기 프로그램이 종료되도록 루프 구간마다 exit 에 대한 코드 복붙으로 (아래와 같이) 넣어주기
// 유효한 숫자 입력받기 메서드
public static int getValidNumber(String prompt, Scanner scanner) {
while (true) {
System.out.println(prompt);
String input = scanner.nextLine();
try {
int num = Integer.parseInt(input);
if (num >= 0) return num;
else System.out.println("0 이상의 수를 입력해주세요.");
} catch (NumberFormatException e) {
System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
}
if (input.equalsIgnoreCase("exit")) {
System.out.println("계산기를 종료합니다.");
System.exit(0); // 프로그램 종료
}
}
}
컬렉션 타입의 필드 results를 활용하여 값을 넣고 제거하는 방법 이해하며 코드 수정
연산 결과를 results 에 추가할 때
results.add(result); // results 에 연산 때마다의 result 를 저장
연산 결과를 삭제할 때
results.remove(); // 배열 형태의 리스트라면 괄호 안에 인덱스 넘버를 넣어 몇 번째를 삭제할지 정할 수 있다
➡️
package firstproject;
public class App {
public static void main(String[] args) {
Calculator calculator = new Calculator();
while (true) {
// 첫 번째 숫자 → 연산자 → 두 번째 숫자 입력 받기 → 연산 수행
int num1 = calculator.getValidNumber("첫 번째 숫자를 입력하세요: ");
char operator = calculator.getValidOperator();
int num2 = calculator.getValidNumber("두 번째 숫자를 입력하세요: ");
// 첫 번째 연산 수행
int result = calculator.performCalculation(num1, num2, operator);
if (result != Integer.MIN_VALUE) {
System.out.println("계산 결과: " + result);
}
// 첫 번째 연산 결과 삭제 원할 때 입력
if (calculator.askForClear()) {
calculator.deleteFirstResult();
continue; // 삭제 후 다시 첫 번째 숫자 입력으로 돌아가기
}
// 마지막 결과값에 추가 연산 여부 묻고 추가 연산 / 프로그램 종료
if (result != Integer.MIN_VALUE && calculator.askForAdditionalOperations()) {
while (true) {
char additionalOperator = calculator.getValidOperator();
int additionalNumber = calculator.getValidNumber("숫자를 입력하세요: ");
result = calculator.performAdditionalOperation(additionalOperator, additionalNumber);
if (result != Integer.MIN_VALUE) {
System.out.println("추가 연산 결과: " + result);
}
if (!calculator.askForAdditionalOperations())
break;
}
}
}
}
}
package firstproject;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Calculator {
public Scanner scanner = new Scanner(System.in);
private List<Integer> results;
public Calculator() {
results = new ArrayList<>();
}
// 유효한 숫자 입력받기 메서드
public int getValidNumber(String prompt) {
while (true) {
System.out.println(prompt);
String input = scanner.nextLine();
try {
int num = Integer.parseInt(input);
if (num >= 0) return num;
else System.out.println("0 이상의 수를 입력해주세요.");
} catch (NumberFormatException e) {
System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
}
}
}
// 유효한 연산자 입력받기 메서드
public char getValidOperator() {
while (true) {
System.out.println("사칙연산(+, -, *, /)을 입력하세요: ");
String input = scanner.nextLine();
if (input.length() == 1 && "+-*/".contains(input)) return input.charAt(0);
else System.out.println("잘못된 입력입니다. 사칙연산 기호를 입력해주세요.");
}
}
// 사칙연산 수행 메서드
public int performCalculation(int num1, int num2, char operator) {
int result;
switch (operator) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 == 0) {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE;
}
result = num1 / num2;
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE;
}
results.add(result);
return result;
}
// 마지막 결과값에 추가 연산 여부 묻기 메서드
public boolean askForAdditionalOperations() {
while (true) {
System.out.print("결과값에 추가 연산을 하시겠습니까? (yes / exit): ");
String input = scanner.nextLine();
if (results.isEmpty()) {
System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");
return false;
}
if (input.equalsIgnoreCase("exit")) {
System.out.println("계산기를 종료합니다.");
System.exit(0); // 프로그램 종료
} else if (input.equalsIgnoreCase("yes")) {
return true;
} else {
System.out.println("잘못된 입력입니다.");
}
}
}
// 마지막 결과값에 추가 연산 수행 메서드
public int performAdditionalOperation(char operator, int number) {
int lastResult = results.get(results.size() - 1);
int result;
switch (operator) {
case '+':
result = lastResult + number;
break;
case '-':
result = lastResult - number;
break;
case '*':
result = lastResult * number;
break;
case '/':
if (number == 0) {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE;
}
result = lastResult / number;
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE;
}
results.add(result);
return result;
}
// 계산기 종료 메서드
public void exitInput() {
while (true) {
String input = scanner.nextLine();
if (input.equalsIgnoreCase("exit")) {
System.out.println("계산기를 종료합니다.");
System.exit(0); // 프로그램 종료
} else {
System.out.println("잘못된 입력입니다.");
}
}
}
// 첫 번째 저장된 연산 결과 삭제 메서드
public void deleteFirstResult() {
String deleteInput = scanner.nextLine();
if (!results.isEmpty() && deleteInput.equalsIgnoreCase("clear")) {
results.remove(0); // 저장된 결과값 있으면 첫번째 결과 삭제
System.out.println("가장 먼저 연산된 결과가 삭제되었습니다.");
} else if (results.isEmpty()) {
System.out.println("삭제할 연산 결과가 없습니다.");
} else {
System.out.println("잘못된 입력입니다.");
}
}
// 첫 번째 연산 결과 삭제 여부 묻기
public boolean askForClear() {
while (true) {
System.out.print("가장 먼저 계산된 결과값을 지우시겠습니까? (clear / no): ");
String input = scanner.nextLine();
if ("clear".equalsIgnoreCase(input)) {
deleteFirstResult();
return true; // 결과 삭제 후 처리 완료
} else if ("no".equalsIgnoreCase(input)) {
return false; // 삭제하지 않겠다고 응답
} else {
System.out.println("잘못된 입력입니다. 'clear' 또는 'no'를 입력하세요.");
}
}
}
}
➡️ 이 코드로는 내가 원하는 동작 흐름이 나오지 않았다.
내가 원하는 코드 동작의 흐름은
이 동작의 흐름대로 구현하기 위해 여러번의 수정을 거듭했다.
package firstproject;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Calculator {
public Scanner scanner = new Scanner(System.in);
private List<Integer> results;
public Calculator() {
results = new ArrayList<>();
}
// 유효한 숫자 입력받기 메서드
public int getValidNumber(String prompt) {
while (true) {
System.out.println(prompt);
String input = scanner.nextLine();
try {
int num = Integer.parseInt(input);
if (num >= 0) return num;
else System.out.println("0 이상의 수를 입력해주세요.");
} catch (NumberFormatException e) {
System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
}
}
}
// 유효한 연산자 입력받기 메서드
public char getValidOperator() {
while (true) {
System.out.println("사칙연산(+, -, *, /)을 입력하세요: ");
String input = scanner.nextLine();
if (input.length() == 1 && "+-*/".contains(input)) return input.charAt(0);
else System.out.println("잘못된 입력입니다. 사칙연산 기호를 입력해주세요.");
}
}
// 사칙연산 수행 메서드
public int performCalculation(int num1, int num2, char operator) {
int result;
switch (operator) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 == 0) {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE;
}
result = num1 / num2;
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE;
}
results.add(result);
return result;
}
// 연산 결과 삭제 여부 묻기 메서드
public boolean askForClear() {
while (true) {
System.out.print("가장 먼저 계산된 결과값을 지우시겠습니까? (clear / no): ");
String input = scanner.nextLine();
if ("clear".equalsIgnoreCase(input)) {
deleteFirstResult();
return true;
} else if ("no".equalsIgnoreCase(input)) {
return false;
} else {
System.out.println("잘못된 입력입니다. 'clear' 또는 'no' 를 입력하세요.");
}
}
}
// 첫 번째 저장된 연산 결과 삭제 메서드
private void deleteFirstResult() {
if (!results.isEmpty()) {
results.remove(0);
System.out.println("가장 먼저 연산된 결과가 삭제되었습니다.");
} else {
System.out.println("삭제할 연산 결과가 없습니다.");
}
}
// 추가 연산 여부 묻기 메서드
public boolean askForAdditionalOperations() {
while (true) {
System.out.print("마지막으로 계산된 값에 추가 연산을 하시겠습니까? (yes / exit): ");
String input = scanner.nextLine();
if (results.isEmpty()) {
System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");
return false;
}
if (input.equalsIgnoreCase("exit")) {
System.out.println("계산기를 종료합니다.");
System.exit(0); // 프로그램 종료
} else if (input.equalsIgnoreCase("yes")) {
return true;
} else {
System.out.println("잘못된 입력입니다.");
}
}
}
// 마지막 결과값에 추가 연산 수행 메서드
public int performAdditionalOperation(char operator, int number) {
int lastResult = results.get(results.size() - 1);
int result;
switch (operator) {
case '+':
result = lastResult + number;
break;
case '-':
result = lastResult - number;
break;
case '*':
result = lastResult * number;
break;
case '/':
if (number == 0) {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE;
}
result = lastResult / number;
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE;
}
results.add(result);
return result;
}
}
package firstproject;
public class App {
public static void main(String[] args) {
Calculator calculator = new Calculator();
while (true) {
int result = performInitialCalculation(calculator);
if (result == Integer.MIN_VALUE) {
continue; // 계산 실패 시 다시 시작
} else if (result != Integer.MIN_VALUE) {
System.out.println("계산 결과: " + result);
}
// 첫 번째 연산 결과 삭제 여부 처리
if (calculator.askForClear()) {
continue; // 삭제 후 다시 첫 번째 숫자 입력으로 돌아가기
}
// 추가 연산 처리
if (!performAdditionalOperations(calculator)) {
break; // 추가 연산이 없으면 종료
}
}
}
// 첫 번째 연산 수행 메서드
public static int performInitialCalculation(Calculator calculator) {
int num1 = calculator.getValidNumber("첫 번째 숫자를 입력하세요: ");
char operator = calculator.getValidOperator();
int num2 = calculator.getValidNumber("두 번째 숫자를 입력하세요: ");
return calculator.performCalculation(num1, num2, operator);
}
// 결과 값에 대한 추가 연산 처리
public static boolean performAdditionalOperations(Calculator calculator) {
if (calculator.askForAdditionalOperations()) {
while (true) {
char additionalOperator = calculator.getValidOperator();
int additionalNumber = calculator.getValidNumber("숫자를 입력하세요: ");
int result = calculator.performAdditionalOperation(additionalOperator, additionalNumber);
if (result != Integer.MIN_VALUE) {
System.out.println("추가 연산 결과: " + result);
}
if (!calculator.askForAdditionalOperations()) {
return false; // 추가 연산이 없으면 종료
}
}
}
return false; // 추가 연산을 하지 않으면 종료
}
}
코드의 가독성과 재사용성을 높이기 위해 최대한 App 클래스의 main 메서드에서는 Calculator 클래스의 메서드를 활용하는 형태로 코딩하려고 노력할 필요성을 느낀다.
또한, 메서드 마다 확실하게 한 가지의 기능을 하도록 코드를 짜는 것이 객체지향성에 걸맞다는 점을 잊지 말자.
가장 애를 먹었던 부분이 Calculator 클래스에서 만든 메서드를 App 클래스로 불러오는 과정에서 가장 힘들었던 것 같다.
아직 문법이 익숙하지 않아서 그런지 내가 원하는 코드의 동작 흐름을 구현하기 위해 코딩할 때마다 잦은 수정이 필요했고 그에 따라 시간이 많이 소요됐다. 하지만, 그 과정에서 문법도 조금 더 익숙해진 것 같고, 코드를 전체적으로 보면서 효율적으로 짜야 한다는 생각도 하게 되었다.