[TIL-CH2] 계산기 과제 트러블슈팅

김유란·2025년 1월 9일

[CH 2 계산기 과제]

  • 필수 기능
    • Lv 1. 클래스 없이 기본적인 연산을 수행할 수 있는 계산기 만들기
    • Lv 2. 클래스를 적용해 기본적인 연산을 수행할 수 있는 계산기 만들기
  • 도전 기능
    • Lv 3. Enum, 제네릭, 람다 & 스트림을 이해한 계산기 만들기

트러블슈팅🚨


1️⃣ 예외 전달 누락으로 인한 오류

💡 배경

Lv3-1의 Enum 타입을 활용하여 연산자 타입을 관리하고 사칙연산 계산기 ArithmeticCalculator 클래스를 구현한 후 실행을 통해 기능 테스트를 진행하던 중에 실행 오류가 발생하였습니다.

🔍 발단

연산 수행 후 예외 처리가 제대로 이루어지지 않는다고 판단하여, 어떤 경우에 오류가 발생하는지 확인하기 위해 다시 실행하며 점검을 진행했습니다.

⚠️ 전개

Enum 타입으로 정의해둔 +, -, *, / 를 첫 연산자로 입력받아 연산 수행 후 부적절한 연산자를 입력하여 예외 처리 된 경우에는 실행 오류가 발생하지 않았습니다.

💣 위기

연산 결과 리스트에 값이 1개라도 있는 경우에는 정상 실행되고 연산이 수행되지 않아 빈 리스트인 경우에만 실행 오류가 발생하고 있다는 것을 알았습니다.

연산이 정상 실행된 경우 main() 메서드에서 calculator.getResult().getLast() 로 계산 결과를 출력하도록 하였는데 빈 리스트일 때 getLast() 가 호출되어 발생한 오류였습니다.

// 연산 조건 만족할 경우 계산 결과 출력
if (pass) System.out.println("결과: " + num1 + operator + num2 + "=" + calculator.getResult().getLast());

✅ 절정

ArithmeticCalculator 클래스에 예외 발생 시 main() 메소드에서 알 수 있도록 pass를 false로 변경하는 부분을 추가하였습니다.

catch (ArithmeticException | IllegalArgumentException e) {
            App.pass = false;  // 예외 발생한 경우 pass를 false로 변경
            System.out.println(e.getMessage());
        }

📌 결말

따라서, 예외 발생으로 인해 결과 리스트가 비어 있을 경우 getLast()를 호출하지 않도록 수정하여 오류를 해결할 수 있었습니다. 또한, NoSuchElementException 등을 활용하여 main() 메서드에서 직접 예외를 처리하는 것도 하나의 방법이 될 수 있습니다.


2️⃣ 메서드 반환 타입 문제

💡 배경

Lv3-3의 Lambda & Stream을 활용하여 메서드를 구현하던 중에 생성한 메서드에 오류가 발생하였습니다.

public LinkedList<Number> maxResult(Number input) {
        return result.stream()
                .filter((Number n) -> input.doubleValue() < n.doubleValue())
                .toList();
}

🔍 발단

오류가 발생한 부분을 보니 public java.util.List<T> toList() 는 스트림의 요소들을 수집하여 List 형태로 반환한다는 것을 알게되었습니다.

⚠️ 전개

maxResult()의 반환 타입은 LinkedList<Number>인데, .toList()를 통해 List 형태로 반환하고 있어 타입 불일치 오류가 발생했습니다.

💣 위기

Java 16 이상에서 사용 가능한 toList()는 스트림에서 처리된 데이터를 하나의 List로 변환하는 스트림의 종료 연산이며, 반환된 리스트는 불변 리스트라는 점을 알게 되었습니다.

toList() 메서드는 List 인터페이스를 구현한 불변 리스트를 반환하므로 LinkedList와 같은 특정 구현체로 변환이 불가능합니다.

✅ 절정

이러한 타입 불일치 문제를 2가지 방식으로 해결할 수 있었습니다.

  1. LinkedListList 로 수정
public List<Number> maxResult(Number input) {
        return result.stream()
                .filter((Number n) -> input.doubleValue() < n.doubleValue())
                .toList();
}
  1. toList() 대신 Collectors.toCollection()을 사용하여 LinkedList로 변환
    • 이 경우 반환되는 리스트는 불변 리스트가 아님
import java.util.stream.Collectors;

public LinkedList<Number> maxResult(Number input) {
        return result.stream()
                .filter((Number n) -> input.doubleValue() < n.doubleValue())
                .collect(Collectors.toCollection(LinkedList::new));  // LinkedList로 변환
}

📌 결말

스트림의 요소들을 수집하여 List 형태로 반환하는 .toList() 에 맞춰 첫 번째 방법을 적용하여 메서드의 반환 타입을 LinkedList 에서 List 로 변경함으로써 오류를 해결할 수 있었습니다.


0개의 댓글