본문 바로가기

개발/Basics

[Java/Basics] 자바 기초 스터디 4주차: 예외처리와 스트림

예외가 무엇인지, 예외 처리가 왜 중요한지 이해하고 예외 처리 방법을 설명하고 스트림으로 넘어가서 개념과 활용법, 데이터를 더욱 효율적으로 처리하는 방법을 익히고자 한다.

 

1. 예외(Exception)란?

 

- 프로그램 실행 중 예상치 못한 오류가 발생하는 상황.

- 예외가 발생하면 프로그램이 비정상적으로 종료될 수 있으므로, 적절한 예외 처리가 필요하다.

 

## 1-1. 예외가 발생하는 대표적 상황

- 잘못된 입력: 숫자를 입력 받아야 하는데 문자가 입력될 경우

- 파일 입출력 오류: 존재하지 않는 파일을 읽으려 할 때

- NullPointException: 객체가 null일 때 메서드를 호출하려는 경우

- ArrayIndexOutOfBoundsException: 배열의 범위를 벗어난 인덱스에 접근하는 경우

 

``` java

public class ExceptionExample {

    public static void main(String[] args) {

        Int[] numbers = {1, 2, 3};

        System.out.println(numbers[5]); // ArrayIndexOutOfBoundsException 발생

    }

}

```

 

# 2. 예외 처리 방법

 

## 2-1. Try-catch 문을 활용한 예외 처리

- 예외가 발생할 가능성이 있는 코드를 try 블록 안에 작성하고, 발생한 예외를 catch 블록에서 처리한다.

 

``` java

public class TryCatchExample {

    public static void main(String[] args) {

        try {

            int result = 10 / 0; // ArithmeticException 발생

        } catch (ArithmeticException e) {

            System.out.println("0으로 나눌 수 없습니다.");

        }

    }

}

```

 

## 2-2. Throws 키워드를 활용한 예외처리

- 메서드에서 예외가 발생할 가능성이 있을 경우, throws를 사용하여 호출한 곳에서 예외를 처리하도록 위임할 수 있다.

 

``` java

public class ThrowsExample {

    public static void divide(int a, int b) throws ArithmeticException {

        If (b == 0) {

            throw new ArithmeticException("0으로 나눌 수 없습니다.");

        }

    System.out.println("결과: " + (a / b));

    }

    public static void main(String[] args) {

         try {

            divide(10, 0);

        } catch (ArithmeticException e) {

            System.out.println(e.getMessage());

        }

    }

}

 

## 2-3. 사용자 정의 예외 만들기

 

- 자바에서 제공하는 기본 예외 클래스 외에도, 사용자 정의 예외를 만들어 특정 상황을 처리할 수 있다.

 

``` java

class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

public class CustomExceptionExample {
    public static void checkAge(int age) throws InvalidAgeException {
        if (age < 18) {
            throw new InvalidAgeException("미성년자는 이용할 수 없습니다.");
        }
        System.out.println("서비스 이용 가능");
    }

    public static void main(String[] args) {
        try {
            checkAge(16);
        } catch (InvalidAgeException e) {
            System.out.println(e.getMessage());
        }
    }
}

```

 

# 스트림(Stream)이란?

 

- 자바 스트림(Stream)은 데이터 컬렉션(List, Set, Map 등)을 쉽고 효율적으로 처리할 수 있도록 해주는 API

- 기존의 for문이나 Iterator를 사용한 반복문보다 더 간결하고 직관적인 코드 작성 가능

 

## 3-1. 스트림의 주요 특징

- 연속적인 데이터 흐름: 데이터가 한 번만 처리되며, 기존 컬렉션을 변경하지 않음.

- 함수형 프로그래밍 방식: map(), filter(), reduce() 등 메서드를 활용한 함수형 스타일의 코드 작성 가능

- 병렬 처리 지원: 병렬 스트림을 활용하면 여러 개의 CPU를 사용하여 성능 향상 가능

 

# 4. 스트림 활용 방법

 

## 4-1. 기본적인 스트림 사용법

``` java

import java.util.Arrays;
import java.util.List;

public class StreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

        // 이름 중 "C"로 시작하는 사람만 필터링
        names.stream()
             .filter(name -> name.startsWith("C"))
             .forEach(System.out::println);
    }
}

```

출력 결과

``` plaintext

Charlie

```

- stream().filter()를 사용하여 "C"로 시작하는 이름만 추출

 

## 4-2. 스트림 메서드 활용

 

(1) map() - 데이터 변환

``` java

List<String> names = Arrays.asList("alice", "bob", "charlie");

names.stream()
     .map(String::toUpperCase)
     .forEach(System.out::println);

```

- map()을 사용하면 문자열을 대문자로 변환 가능

 

(2) sorted() - 정렬

``` java

List<Integer> numbers = Arrays.asList(5, 2, 9, 1, 3);

numbers.stream()
       .sorted()
       .forEach(System.out::println);

```

- sorted()를 사용하여 리스트 정렬 가능

 

(3) reduce() - 누적 연산

``` java

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

int sum = numbers.stream()
                 .reduce(0, Integer::sum);

System.out.println(sum); // 15

```

- reduce()를 활용하면 리스트의 모든 값 합산 가능

 

# 5. 결론 및 요약

- 예외처리는 프로그램의 안정성을 높이며, try-catch, throws, 사용자 정의 예외를 활용 가능

- 스트림(Stream)을 활용하면 더 간결하고 직관적 방식으로 데이터를 처리 가능

- 스트림은 함수형 프로그래밍 스타일을 지원하며 map(), filter(), reduce()등의 메서드를 활용해 다양한 연산을 수행할 수 있다.