첫 개인 프로젝트라 문법 이해와 학습을 위해 코드마다 메모처럼 주석처리를 했다. 나중에 익숙해진 문법들부터 차차 주석 제거 예정이다.
요구사항 체크리스트 ⬜✅ :
사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 컬렉션 타입 필드를 사진 Calculator 클래스를 생성
✅ 사칙연산을 수행한 후, 결과값을 반환하는 메서드 구현
✅ 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
✅ 1) 양의 정수 2개(0 포함)와 연산 기호를 매개변수로 받아 사칙연산(➕,➖,✖️,➗) 기늘을 수행한 후,
2) 결과 값을 반환하는 메서드와 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
package firstproject;
import java.util.ArrayList;
import java.util.List;
public class Calculator {
// 연산 결과를 저장하는 컬렉션 필드
public List<Integer> results;
// 생성자
public Calculator() {
results = new ArrayList<>(); // 연산 결과를 저장할 ArrayList 초기화
}
// 사칙연산 수행
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) {
result = num1 / num2;
} else {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE; // 에러 표시
}
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE; // 에러 표시
}
// 결과를 리스트에 저장
results.add(result);
return result;
}
}
Lv1에서 구현한 App 클래스의 main 메서드에 Calculator 클래스가 활용될 수 있도록 수정
✅ 연산 수행 역할은 Calculator 클래스가 담당
✅ 연산 결과는 Calculator 클래스의 연산 결과를 저장하는 필드에 저장
✅ 소스 코드 수정 후에도 수정 전의 기능들이 반드시 똑같이 동작해야 한다
package firstproject;
import java.util.Scanner;
public class App {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Calculator calculator = new Calculator();
while (true) { // "exit"를 입력하기 전까지 계속 반복
// 첫 번째 숫자 입력받기
int num1 = getValidNumber(scanner, "첫 번째 숫자를 입력하세요: ");
// 사칙연산 입력받기
char operator = getValidOperator(scanner);
// 두 번째 숫자 입력받기
int num2 = getValidNumber(scanner, "두 번째 숫자를 입력하세요: ");
// 사칙연산 수행 후 결과 출력
int result = calculator.performCalculation(num1, num2, operator);
// Calculator 클래스의 performCalculation 호출
if (result != Integer.MIN_VALUE) {
System.out.println("계산 결과: " + result);
}
// 계속 계산할지 물어보기
if (!getContinueInput(scanner)) {
System.out.println("계산기를 종료합니다.");
return;
}
}
}
// 숫자 입력받기 (유효성 검사 포함)
private static int getValidNumber(Scanner scanner, String prompt) {
int num;
while (true) {
System.out.println(prompt);
String input = scanner.nextLine();
try {
num = Integer.parseInt(input);
if (num >= 0) {
return num;
} else {
System.out.println("0 이상의 수를 입력해주세요.");
}
} catch (NumberFormatException e) {
System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
}
}
}
// 사칙연산 입력받기
private static char getValidOperator(Scanner scanner) {
while (true) {
System.out.println("사칙연산(+, -, *, /)을 입력하세요: ");
String operatorInput = scanner.nextLine();
if (operatorInput.length() == 1 && "+-*/".indexOf(operatorInput.charAt(0)) != -1) {
return operatorInput.charAt(0);
} else {
System.out.println("잘못된 입력입니다. 사칙연산 기호를 입력해주세요.");
}
}
}
// 계속 계산할지 묻기
private static boolean getContinueInput(Scanner scanner) {
while (true) {
System.out.println("계속 계산하시겠습니까? (yes / exit): ");
String continueInput = scanner.nextLine();
if (continueInput.equalsIgnoreCase("exit")) {
return false;
} else if (continueInput.equalsIgnoreCase("yes")) {
return true;
} else {
System.out.println("잘못된 입력입니다. 'yes' 또는 'exit' 를 입력해주세요.");
}
}
}
}
// 추후에 추가할 것
// 속성, 생성자, 기능 주석 구분
// 괄호 사용
// 제곱
// Clear 기능
// 나누기 결과 소수점까지 표시
➡️
Calculator calculator = new Calculator();
calculator 객체를 생성해주고,
// 사칙연산 수행 후 결과 출력
int result = calculator.performCalculation(num1, num2, operator);
Calculator 클래스의 사칙연산 수행 메서드(performCalculation)를 호출해주고,
App 클래스 안의 사칙연산 수행 메서드는 깔끔하게 지워줬다
App 클래스의 main 메서드에서 Calculator 클래스의 연산 결과를 저장하고 있는 컬렉션 필드에 직접 접근하지 못하도록 수정(캡슐화)
✅ 간접 접근을 통해 필드에 접근하여 가져올 수 있도록 구현 (Getter 메서드)
✅ 간접 접근을 통해 필드에 접근하여 수정할 수 있도록 구현 (Setter 메서드)
✅ 위 요구사항을 모두 구현 했다면 App 클래스의 main 메서드에서 위에서 구현한 메서드를 활용해보자
package firstproject;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Calculator {
// 연산 결과를 저장하는 컬렉션 필드
private List<Integer> results; // private 으로 설정하여 외부에서 직접 점근 불가
// 생성자
public Calculator() {
results = new ArrayList<>(); // 연산 결과를 저장할 ArrayList 초기화
}
// 사칙연산 수행 메서드
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) {
result = num1 / num2;
} else {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE; // 에러 표시
}
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE; // 에러 표시
}
// 결과를 리스트에 저장
results.add(result);
return result;
}
// 연산 결과 리스트를 반환하는 getter 메서드
public List<Integer> getResults() {
return new ArrayList<>(results); // results 의 복사본을 반환하여 외부에서 수정 못 하게 하기
}
// 연산 결과는 수정할 수 없지만, 연산 결과에 또 연산을 할 수 있는 setter 메서드
// 마지막 연산 결과에 추가 연산 수행 메서드
public int performAdditionalOperation(char operator, int number) {
if (results.isEmpty()) {
System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");
// 계속 계산할지 묻기
if (!getContinueInput()) {
return Integer.MIN_VALUE; // exit 를 입력하면 연산 종료
} else {
return Integer.MIN_VALUE; // yes 를 입력하면 추가 연산 없이 프로그램 계속 실행
}
}
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) {
result = lastResult / number;
} else {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE; // 에러 표시
}
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE; // 에러 표시
}
// 새로운 결과를 리스트에 저장
results.add(result);
return result;
}
// 계속 계산할지 묻기
private boolean getContinueInput() {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("계속 계산하시겠습니까? (yes / exit): ");
String continueInput = scanner.nextLine();
if (continueInput.equalsIgnoreCase("exit")) {
return false;
} else if (continueInput.equalsIgnoreCase("yes")) {
return true;
} else {
System.out.println("잘못된 입력입니다. 'yes' 또는 'exit' 를 입력해주세요.");
}
}
}
}
➡️
// 연산 결과를 저장하는 컬렉션 필드
private List<Integer> results;
private 으로 설정하여 외부에서 직접 접근이 불가하도록 해주고,
// 연산 결과 리스트를 반환하는 getter 메서드
public List<Integer> getResults() {
return new ArrayList<>(results);
results의 복사본을 반환하여 외부에서 수정 못 하도록 하고,
// 연산 결과는 수정할 수 없지만, 연산 결과에 또 연산을 할 수 있는 setter 메서드
// 마지막 연산 결과에 추가 연산 수행 메서드
public int performAdditionalOperation(char operator, int number) {
if (results.isEmpty()) {
System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");
// 계속 계산할지 묻기
if (!getContinueInput()) {
return Integer.MIN_VALUE; // exit 를 입력하면 연산 종료
} else {
return Integer.MIN_VALUE; // yes 를 입력하면 추가 연산 없이 프로그램 계속 실행
}
}
연산 결과가 없을 경우, 에러 메시지 출력 후에 계산기 프로그램의 계속 진행/종료 여부를 물어보고,
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) {
result = lastResult / number;
} else {
System.out.println("0으로 나눌 수 없습니다.");
return Integer.MIN_VALUE; // 에러 표시
}
break;
default:
System.out.println("잘못된 연산자입니다.");
return Integer.MIN_VALUE; // 에러 표시
}
// 새로운 결과를 리스트에 저장
results.add(result);
return result;
마지막 연산 결과가 있고 추가 연산을 원할 경우, 추가 연산 진행을 위한 메서드를 추가해주고,
// 계속 계산할지 묻기
private static boolean getContinueInput() {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("계속 계산하시겠습니까? (yes / exit): ");
String continueInput = scanner.nextLine();
if (continueInput.equalsIgnoreCase("exit")) {
return false;
} else if (continueInput.equalsIgnoreCase("yes")) {
return true;
} else {
System.out.println("잘못된 입력입니다. 'yes' 또는 'exit' 를 입력해주세요.");
}
}
}
각 계산이 끝날 때마다 또 계산을 원하는지, 아니면 프로그램의 종료를 원하는지 물어보도록 마지막 부분에 코드 또 추가 (App 클래스에서 프로그램 종료 여부 묻는 코드 부분 가져온 다음 수정)
➡️ 수정한 코드를 실행해보니 추가 연산을 수행한 후에 또 추가 연산을 실행할지 물어보는 루프가 없어서 코드의 동작 흐름이 예상했던 것과 다르게 흘러갔다

내가 원한 건 추가 연산도 끝낼 때마다 계속 물어보길 원했기 때문에 다시 수정
package firstproject;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Calculator {
private List<Integer> results;
public Calculator() {
results = new ArrayList<>();
}
// 사칙연산 수행
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 int performAdditionalOperation(char operator, int number) {
if (results.isEmpty()) {
System.out.println("연산 결과가 없습니다. 먼저 계산을 수행해주세요.");
return Integer.MIN_VALUE;
}
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 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("잘못된 입력입니다. 숫자만 입력해주세요.");
}
}
}
// 유효한 연산자 입력받기
public static char getValidOperator(Scanner scanner) {
while (true) {
System.out.println("사칙연산(+, -, *, /)을 입력하세요: ");
String input = scanner.nextLine();
if (input.length() == 1 && "+-*/".contains(input)) return input.charAt(0);
else System.out.println("잘못된 입력입니다. 사칙연산 기호를 입력해주세요.");
}
}
// 추가 연산 여부 묻기
public static boolean askForAdditionalOperations(Scanner scanner) {
while (true) {
System.out.print("추가 연산을 하시겠습니까? (yes / exit): ");
String input = scanner.nextLine();
if (input.equalsIgnoreCase("exit")) {
System.out.println("계산기를 종료합니다.");
System.exit(0); // 프로그램 종료
} else if (input.equalsIgnoreCase("yes")) {
return true;
} else {
System.out.println("잘못된 입력입니다.");
}
}
}
}
package firstproject;
import java.util.Scanner;
public class App {
public static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
Calculator calculator = new Calculator();
while (true) {
// 첫 번째 숫자와 연산자 입력
int num1 = Calculator.getValidNumber("첫 번째 숫자를 입력하세요: ", scanner);
char operator = Calculator.getValidOperator(scanner);
int num2 = Calculator.getValidNumber("두 번째 숫자를 입력하세요: ", scanner);
// 첫 번째 연산 수행
int result = calculator.performCalculation(num1, num2, operator);
if (result != Integer.MIN_VALUE) {
System.out.println("계산 결과: " + result);
}
// 추가 연산 여부 묻기
if (result != Integer.MIN_VALUE && Calculator.askForAdditionalOperations(scanner)) {
while (true) {
char additionalOperator = Calculator.getValidOperator(scanner);
int additionalNumber = Calculator.getValidNumber("숫자를 입력하세요: ", scanner);
result = calculator.performAdditionalOperation(additionalOperator, additionalNumber);
if (result != Integer.MIN_VALUE) {
System.out.println("추가 연산 결과: " + result);
}
if (!Calculator.askForAdditionalOperations(scanner))
break;
}
// 추가 연산을 계속할지 물어봄
if (!Calculator.askForAdditionalOperations(scanner)) {
break; // 더 이상 추가 연산을 원하지 않으면 루프를 종료
}
}
}
}
}
참고로 이때쯤 내 뇌는 이미 나의 것이 아니었..🫡🙃
다음에 추가해야 할 코드
Calcualtor 클래스에서 저장된 연산 결과들 중 가장 먼저 저장된 데이터를 삭제하는 기능을 가진 메서드를 구현한 후 App 클래스의 main 메서드에 삭제 메서드가 활용될 수 있도록 수정
⬜ 키워드 : 컬렉션
⬜ 컬렉션에서 '값을 넣고 제거하는 방법을 이해하는 것'이 중요!