내배캠 TIL 11일차

오병택·2025년 3월 4일

내배캠

목록 보기
33/73

11일차 요약

lv2 계산기 개선사항 반영, 자바 강의

lv2 계산기

코드 1

package com.example.calculator;

import java.util.InputMismatchException;
import java.util.Scanner;

public class App {
    public static void main(String[] args) {
        Calculator cal = new Calculator();
        Scanner scanner = new Scanner(System.in);
        boolean exit = true;
        while (exit) {
            long x;
            long y;
            Number result;
            while (true) {
                try {
                    System.out.print("첫 번째 양의 정수(0 포함)를 입력해주세요: ");
                    x = scanner.nextLong();
                    System.out.print("두 번째 양의 정수(0 포함)를 입력해주세요: ");
                    y = scanner.nextLong();
                    if (x < 0 || y < 0) {
                        System.out.println("음수를 적으셨습니다. 다시 입력해주세요.");
                        continue;
                    }

                } catch (InputMismatchException e) {
                    scanner.nextLine();
                    System.out.println("숫자만 입력해주세요");
                    continue;
                }
                while (true) {
                    try{
                        System.out.print("사칙연산 기호를 입력하세요: ");
                        char oper = scanner.next().charAt(0);
                        result = cal.calculate(x, oper, y); // 계산 값을 반환
                        System.out.println("계산 값: " + result);
                        break;
                    }catch (ArithmeticException | IllegalArgumentException e) {
                        System.out.println(e.getMessage());
                    }
                }

                System.out.println("값을 저장소에 저장합니다");
                cal.setResultSave(result);
                System.out.println(cal.getResultSave());

                System.out.println("저장소에 저장된 첫 번째 값을 삭제를 원하시면 1, 아니면 0을 써주세요");
                int s = scanner.nextInt();
                if (s == 1) {
                    cal.removeResult();
                    System.out.println(cal.getResultSave());
                }
                break;
            }

            scanner.nextLine();
            System.out.println("더 계산하시겠습니까? (exit 입력시 종료, 다른 입력시 계속)");
            String q = scanner.nextLine();
            if (q.equals("exit")) {
                exit = false;
                System.out.println("종료하겠습니다");
            }
        }
    }

}

코드 2

package com.example.calculator;

import java.util.ArrayList;
import java.util.List;

public class Calculator {
    private final List<Number> resultSave = new ArrayList<>();

    public Number calculate(long x, char oper, long y) {
        return switch (oper) {
            case '+' -> x + y;
            case '-' -> x - y;
            case '*' -> x * y;
            case '/' -> {
                if (y == 0) {
                    throw new ArithmeticException("0으로 나눌 수 없습니다. 다시 입력해주세요");
                }
                yield x / (double) y;
            }
            default -> throw new IllegalArgumentException("연산기호가 잘못됐습니다. 다시 입력해주세요");

        };
    }


    public List<Number> getResultSave() {
        return this.resultSave;
    }

    public void setResultSave(Number result) {
        this.resultSave.add(result);
    }

    public void removeResult() {
        if (resultSave.isEmpty()) {
            System.out.println("저장소가 비어있습니다");
        }
        resultSave.remove(0);
    }
}

고민한 부분

  • Object 타입을 안 쓰면 어떤 걸 받아야 실수도 받을 수 있지?
  • 클래스를 어떻게 나누면 좋을까?

해결한 부분

  • Number 타입을 쓰면 정수, 실수 둘 다 받을 수 있고 타입을 지정할 수 있다.
  • 10일차에 들었던 튜터님이 알려준 개선사항 수정 (getter로는 저장소 보여주게끔 하고 setter로는 값을 추가해주는 것으로 수정)
  • 클래스를 일단 inputoutput으로 하나를 더 만들어서 분리

끝나갈 무렵에 갑자기 집중 잘 돼서 분리함

코드 수정 1 (inputoutput 클래스 하나 만들어서 분리)

package com.example.calculator;

public class App {
    public static void main(String[] args) {
        Calculatorio calculatorio = new Calculatorio();
        boolean exit = true;
        while (exit) {
            calculatorio.longInput();
            calculatorio.operationInput();
            calculatorio.resultSaveInput();
            calculatorio.exitInput();
        }
    }
}

코드 수정 2(Calculatorio 클래스 하나 추가)

package com.example.calculator;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Calculatorio {
    Calculator cal = new Calculator();
    Scanner scanner = new Scanner(System.in);
    long x;
    long y;
    Number result;
    public void longInput() {
        while (true) {
            try {
                System.out.print("첫 번째 양의 정수(0 포함)를 입력해주세요: ");
                x = scanner.nextLong();
                System.out.print("두 번째 양의 정수(0 포함)를 입력해주세요: ");
                y = scanner.nextLong();
                if (x < 0 || y < 0) {
                    System.out.println("음수를 적으셨습니다. 다시 입력해주세요.");
                }
                break;
            } catch (InputMismatchException e) {
                scanner.nextLine();
                System.out.println("숫자만 입력해주세요");
            }
        }
    }

    public void operationInput() {
        while (true) {
            try {
                System.out.print("사칙연산 기호를 입력하세요: ");
                char oper = scanner.next().charAt(0);
                result = cal.calculate(x, oper, y); // 계산 값을 반환
                System.out.println("계산 값: " + result);
                break;
            } catch (ArithmeticException | IllegalArgumentException e) {
                System.out.println(e.getMessage());
            }
        }

    }

    public void resultSaveInput() {
        boolean flag = true;
        while (flag) {
            System.out.println("값 저장(0), 값 삭제(1), 값 조회(2), 넘어가기(아무거나 입력)");
            int num = scanner.nextInt();
            switch (num) {
                case 0 -> cal.setResultSave(result);
                case 1 -> {
                    if (cal.getResultSave().isEmpty()) {
                        System.out.println("저장소가 비어있습니다.");
                    }
                    cal.removeResult();
                }
                case 2 -> System.out.println(cal.getResultSave());
                default -> flag=false;
            }
        }
    }

    public boolean exitInput() {
        scanner.nextLine();
        boolean exit=true;
        System.out.println("더 계산하시겠습니까? (exit 입력시 종료, 다른 입력시 계속)");
        String q = scanner.nextLine();
        if (q.equals("exit")) {
            System.out.println("종료하겠습니다");
            exit=false;
        }
        return exit;
    }

}

Java

익명 클래스

이름이 없는 클래스

ex)

public interface Calculator {

    int sum(int a, int b);
}
public class Main {

    public static void main(String[] args) {
    
        Calculator calculator1 = new Calculator() { // 익명 클래스 
            @Override
            public int sum(int a, int b) {
                return a + b;
            }
        };
        
        int ret1 = calculator1.sum(1, 1);
        System.out.println("ret1 = " + ret1);
    }
}

람다

익명 클래스를 더 간결하게 표현하는 문법

  • 함수형 인터페이스를 통해서 구현하는 것을 권장
    이유 : 여러 개의 메서드를 가지고 있으면 컴파일러가 어떤 것을 써야 할 지 구분이 안 됨.
    그래서 하나의 추상 메서드만 가지도록 강제하는 함수형 인터페이스를 사용하는 것.

ex)

public interface Calculator {
    int sum(int a, int b);
}
public class Main {
    public static void main(String[] args) {

        Calculator cal1 = new Calculator() {
            @Override
            public int sum(int a, int b) {
                return a + b;
            }
        };

        int ret3 = calculate(3, 3, cal1);
        System.out.println("ret3 = " + ret3); // 방식 1

        Calculator cal2 = (a,b) -> a + b;
        int ret4 = calculate(4,4,cal2);
        System.out.println("ret4 = " + ret4); // 방식 2
        
        int ret5 = calculate(5,5,(a, b) -> a+b);
        System.out.println("ret5 = " + ret5); // 방식 3
    }
    public static int calculate(int a, int b, Calculator calculator) {
        return calculator.sum(a, b);
    }
}

스트림

데이터를 효율적으로 처리할 수 있는 흐름

  • 선언형 스타일로 가독성 뛰어남
  • 데이터> 중간연산> 최종 연산 순으로 처리

느낀 점

10일차에 받은 개선사항 중에서 클래스 분리 빼고는 다 했는데 클래스 분리를 하려고 하니까 집중이 안 돼서 긴장 풀 겸 남은 강의를 들었다. 안 되는 것 붙잡고 계속 억지로 하려고 하는 것보다 잠깐 리프레쉬하고 오는 것이 더 잘 된다는 것을 느꼈다. 어찌저찌 분리 성공.. 만족스럽진 않지만 내일 해야 겠다..

profile
걱정하지 말고 일단 해봐!

0개의 댓글