반응형
목차
🧮 계산기
Lv1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기.
1. 개발 조건 및 코드
조건
- 양의 정수(0 포함)를 입력받기
- 사칙연산 기호(➕,➖,✖️,➗)를 입력받기
- 위에서 입력받은 양의 정수 2개와 사칙연산 기호를 사용하여 연산을 진행한 후 결과값을 출력하기
- 반복문을 사용하되, 반복의 종료를 알려주는 “exit” 문자열을 입력하기 전까지 무한으로 계산을 진행할 수 있도록 소스 코드를 수정하기
[Lv1. 완성 코드]
더보기
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
// Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기
// 양의 정수(0 포함)를 입력받기
System.out.print("첫번째 숫자를 입력해주세요: ");
int num1 = input.nextInt();
System.out.print("두번째 숫자를 입력해주세요: ");
int num2 = input.nextInt();
if(num1 < 0 || num2 < 0){
System.out.println("0을 포함한 양의 정수만 입력하세요!");
continue;
}
System.out.print("사칙연산 기호(+, -, *, /)를 입력하세요: ");
String operator = input.next();
//버퍼 비우기
input.nextLine();
char oper = operator.charAt(0);
int result = 0;
switch (oper) {
case '+':
result = num1 + num2;
System.out.println("결과: " + result);
break;
case '-':
result = num1 - num2;
System.out.println("결과: " + result);
break;
case '*':
result = num1 * num2;
System.out.println("결과: " + result);
break;
case '/':
try{
result = num1 / num2;
System.out.println("결과: " + result);
}catch(ArithmeticException e){
System.out.println("나눗셈 연산에서 두번째 정수에 0을 입력할 수 없습니다.");
}
break;
default:
System.out.println("잘못된 연산자를 입력하셨습니다!");
}
System.out.println("결과: " + result);
//계속 계산할건지 체크
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
String answer = input.nextLine();
if(answer.equals("exit")){
System.exit(0);
}
}
}
}
2. 트러블 슈팅(문제 해결)
❗문제 상황
- 반복 종료를 알려주는 exit 문자열을 입력하려고 할 때, 문자열 입력이 생략되고 바로 반복문이 시작되는 문제가 있었다.
❗문제 발생 이유
- nextInt()는 Enter나 공백을 기준으로 int형 값을 가져온다. 그러면 큐에 Enter 값이 남아있게 된다.
- 문자열을 받아오려면 nextLine()을 사용하게 되는데, 그 때 큐에 남아있는 공백문자열이 바로 출력되어 넘어가기 때문에 입력을 할 수 없는 것이었다.
❗ 해결 과정
- 값을 아무것도 입력하지 않는 input.nextLine(); 을 한 번 더 작성하여 버퍼를 비워주었다.
❗새로 알게 된 것
- nextInt() 사용 시 큐에 Enter 값이 남아있게 된다는 것을 새로 알게 되었다.
(참고한 글)
[JAVA] scanner 버퍼 비우기
JAVA를 사용할 때 Scanner는 정말 많이 쓰이는 라이브러리입니다.
medium.com
Lv 2. 클래스를 적용해 기본적인 연산을 수행할 수 있는 계산기 만들기.
1. 개발 조건 및 코드
조건
- 사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
- Lv 1에서 구현한 App 클래스의 main 메서드에 Calculator 클래스가 활용될 수 있도록 수정
- App 클래스의 main 메서드에서 Calculator 클래스의 연산 결과를 저장하고 있는 컬렉션 필드에 직접 접근하지 못하도록 수정
- Calculator 클래스에 저장된 연산 결과들 중 가장 먼저 저장된 데이터를 삭제하는 기능을 가진 메서드를 구현한 후 App 클래스의 main 메서드에 삭제 메서드가 활용될 수 있도록 수정
[Lv2. 완성코드]
더보기
package calculator;
import java.util.ArrayList;
public class Calculator {
int num1;
int num2;
int result;
// 결과 값을 담을 list
// 캡슐화
// 인텔리제이는 왜 final을 추천할까? -> 불변객체?
private final ArrayList<Integer> list = new ArrayList<Integer>();
public void setNum1(int num1){
isNum();
this.num1 = num1;
}
public void setNum2(int num2){
isNum();
this.num2 = num2;
}
public boolean isNum(){
if(this.num1 <= -1 || this.num2 <= -1){
return false;
}
return true;
}
public int sum() {
result = this.num1 + this.num2;
return result;
}
public int subtract(){
result = this.num1 - this.num2;
return result;
}
public int multiply(){
result = this.num1 * this.num2;
return result;
}
public int division(){
try{
result = this.num1 / this.num2;
// 계산이 될 경우에만 list에 값 저장.
setList(result);
}catch (ArithmeticException e){
System.out.println("나눗셈 연산에서 두번째 정수에 0을 입력할 수 없습니다.");
}
return result;
}
// list의 getter, setter
public void setList(int result){
this.list.add(result);
}
public ArrayList<Integer> getList(){
return this.list;
}
// 가장 먼저 저장된 데이터 삭제
public void removeList(){
try{
this.list.remove(0);
}catch(IndexOutOfBoundsException e){
System.out.println("저장된 값이 없습니다.");
}
}
}
import calculator.Calculator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 반복문 실행 시에 초기화되는 일을 막기 위해 반복문 밖에 작성.
Calculator calculator = new Calculator();
Scanner input = new Scanner(System.in);
while (true) {
// Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기
// 양의 정수(0 포함)를 입력받기
System.out.print("첫번째 숫자를 입력해주세요: ");
int num1 = input.nextInt();
System.out.print("두번째 숫자를 입력해주세요: ");
int num2 = input.nextInt();
// setter로 calculator 클래스에 값 넘기기.
// calculator 클래스에서 0을 포함한 정수 체크
calculator.setNum1(num1);
calculator.setNum2(num2);
if (!calculator.isNum()) {
System.out.println("0을 포함한 양의 정수만 입력하세요!");
continue;
}
System.out.print("사칙연산 기호(+, -, *, /)를 입력하세요: ");
String operator = input.next();
//버퍼 비우기
input.nextLine();
char oper = operator.charAt(0);
int result = 0;
switch (oper) {
case '+':
result = calculator.sum();
calculator.setList(result);
break;
case '-':
result = calculator.subtract();
calculator.setList(result);
break;
case '*':
result = calculator.multiply();
calculator.setList(result);
break;
case '/':
// try~catch 문 Calculator 클래스로 이동.
result = calculator.division();
break;
default:
System.out.println("잘못된 연산자를 입력하셨습니다!");
}
System.out.println("결과: " + result);
System.out.println("저장된 계산결과: " + calculator.getList());
//계속 계산할건지 체크
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
String answer = input.nextLine();
if (answer.equals("exit")) {
System.exit(0);
}
System.out.println("계산한 값을 지우시겠습니까? yes 입력 시 가장 먼저 저장된 데이터가 삭제됩니다.");
String erase = input.nextLine();
if(erase.equals("yes")){
calculator.removeList();
System.out.println("삭제 후 저장된 결과: " + calculator.getList());
}
}
}
}
2. 트러블 슈팅(문제 해결)
❗문제 상황
- 계산 결과 값을 List 에 담는 과정에서 값이 계속 초기화 되는 문제가 발생하였다.
❗문제 발생 이유
- while 문이 반복하면서 Calculator.java를 다시 인스턴스화 하기 때문에 list 안에 있던 기존값들이 초기화 될 수 밖에 없다.
❗해결 과정
- 처음에는 getter와 setter이 문제인 줄 알고 계속 그 부분의 코드만 수정하였으나 개선되지 않았다.
- while문 안에 있던 Calculator calculator = new Calculator(); 코드를 while문 밖으로 이동시켜보았더니 해결되었다.
❗새로 알게 된 것
- while문 밖에서 인스턴스화를 해야 while문이 돌면서 인스턴스도 같이 초기화 되는 일을 막을 수 있다.
Lv3. Enum, 제네릭, 람다 & 스트림을 이해한 계산기 만들기
조건
- Enum 타입을 활용하여 연산자 타입에 대한 정보를 관리하고 이를 사칙연산 계산기 ArithmeticCalculator 클래스에 활용
[Lv3. 코드]
더보기
OperatorType.java
package calculator;
public enum OperatorType {
PLUS('+'){
public int apply(int num1, int num2){
return num1 + num2;
}
},
MINUS('-'){
public int apply(int num1, int num2){
return num1 - num2;
}
},
MUL('*'){
public int apply(int num1, int num2){
return num1 * num2;
}
},
DIV('/'){
public int apply(int num1, int num2){
return num1 / num2;
}
};
//생성자
OperatorType(char oper) {
this.oper = oper;
}
private final char oper;
public static OperatorType getOperate(char operate) {
if(OperatorType.PLUS.oper == operate){
return OperatorType.PLUS;
} else if (OperatorType.MINUS.oper == operate) {
return OperatorType.MINUS;
} else if(OperatorType.MUL.oper == operate){
return OperatorType.MUL;
}else if(OperatorType.DIV.oper == operate){
return OperatorType.DIV;
}else{
throw new RuntimeException();
}
}
public abstract int apply(int num1, int num2);
}
Calculator.java
package calculator;
import java.util.ArrayList;
public class Calculator{
int num1;
int num2;
int result;
// 결과 값을 담을 list
// 캡슐화
// 인텔리제이는 왜 final을 추천할까? -> 불변객체?
private final ArrayList<Integer> list = new ArrayList<Integer>();
public void setNum1(int num1){
isNum();
this.num1 = num1;
}
public void setNum2(int num2){
isNum();
this.num2 = num2;
}
public boolean isNum(){
if(this.num1 <= -1 || this.num2 <= -1){
return false;
}
return true;
}
// list의 getter, setter
public void setList(int result){
this.list.add(result);
}
public ArrayList<Integer> getList(){
return this.list;
}
// 가장 먼저 저장된 데이터 삭제
public void removeList(){
try{
this.list.remove(0);
}catch(IndexOutOfBoundsException e){
System.out.println("저장된 값이 없습니다.");
}
}
}
Main.java
import calculator.Calculator;
import calculator.OperatorType;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 반복문 실행 시에 초기화되는 일을 막기 위해 반복문 밖에 작성.
Calculator calculator = new Calculator();
Scanner input = new Scanner(System.in);
while (true) {
// Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기
// 양의 정수(0 포함)를 입력받기
System.out.print("첫번째 숫자를 입력해주세요: ");
int num1 = input.nextInt();
System.out.print("두번째 숫자를 입력해주세요: ");
int num2 = input.nextInt();
// setter로 calculator 클래스에 값 넘기기.
// calculator 클래스에서 0을 포함한 정수 체크
calculator.setNum1(num1);
calculator.setNum2(num2);
if (!calculator.isNum()) {
System.out.println("0을 포함한 양의 정수만 입력하세요!");
continue;
}
System.out.print("사칙연산 기호(+, -, *, /)를 입력하세요: ");
String operator = input.next();
//버퍼 비우기
input.nextLine();
char op = operator.charAt(0);
OperatorType operType = OperatorType.getOperate(op);
int result = 0;
switch (operType) {
case PLUS:
result = OperatorType.PLUS.apply(num1, num2);
calculator.setList(result);
break;
case MINUS:
result = OperatorType.MINUS.apply(num1, num2);
calculator.setList(result);
break;
case MUL:
result = OperatorType.MUL.apply(num1, num2);
calculator.setList(result);
break;
case DIV:
// enum 사용으로 인해 try ~ catch 문 다시 복구.
try{
result = OperatorType.DIV.apply(num1, num2);
// 계산이 될 경우에만 list에 값 저장.
calculator.setList(result);
}catch (ArithmeticException e){
System.out.println("나눗셈 연산에서 두번째 정수에 0을 입력할 수 없습니다.");
}
break;
default:
System.out.println("잘못된 연산자를 입력하셨습니다!");
}
System.out.println("결과: " + result);
System.out.println("저장된 계산결과: " + calculator.getList());
//계속 계산할건지 체크
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
String answer = input.nextLine();
if (answer.equals("exit")) {
System.exit(0);
}
System.out.println("계산한 값을 지우시겠습니까? yes 입력 시 가장 먼저 저장된 데이터가 삭제됩니다.");
String erase = input.nextLine();
if(erase.equals("yes")){
calculator.removeList();
System.out.println("삭제 후 저장된 결과: " + calculator.getList());
}
}
}
}
- Lv3 은 enum을 사용하는 조건만 해결하였다.
2. 트러블 슈팅(문제 해결)
❗문제 상황
- main.java 에서 입력한 ➕,➖,✖️,➗ 기호를 받아오기 위한 getOperate() 메서드를 Enum 클래스에 작성하였는데 받아오지 못하는 이슈가 발생하였다.
❗문제 발생 이유
- main.java 에서는 char 타입인데 OperatorType은 OperatorType 이라는 반환 자료형 형태이기 때문에 자료형 형태가 맞지 않았다.
❗해결 과정
- Enum 클래스에서 생성자를 생성해주었고 이를 통해 받아온 데이터를 if문을 이용해 비교하여 계산할 수 있도록 해주었다.
❗새로 알게 된 것
- Enum의 상수를 설정할 때는 대문자를 사용해야 한다.
- 생성자를 만들어서 받아온 후 받아온 데이터를 비교한 뒤에 상수와 조건을 설정해 준 부분으로 넘어가서 내가 원하는 계산을 하게 된다.
🤓 회고
Lv3 까지 다 풀어보고 싶었는데 강의와 병행하면서 과제를 하는 게 쉽지 않았다. 특히 강의를 먼저 들어야 과제를 해결할 수 있었기 때문에 필수 해결 과제를 풀기 위해서 꼭 들어야 하는 강의까지 듣고 급하게 과제를 시작해야했다. 그렇지만 이번 과제를 진행하면서 강의에서 배웠던 것들 중 어느 부분이 이해도가 부족한 지에 대해서도 알 수 있는 계기가 되어 좋았다.
다음 과제에서는 시간 분배를 잘해서 도전 과제까지 다 끝내보고 싶다!
반응형
'스파르타 내일배움캠프 > TIL(Today I learned)' 카테고리의 다른 글
25.03.10 TIL - 예외처리 (2) | 2025.03.10 |
---|---|
25.03.07 TIL - 다형성 (2) | 2025.03.07 |
25.03.05 TIL - 캡슐화, 상속, 추상화 (2) | 2025.03.05 |
25.03.04 TIL - final, interface, Lv2. 계산기 과제 (3) | 2025.03.04 |
25.02.28 TIL - Wrapper Class, static, final, Interface (2) | 2025.02.28 |