개발은 재밌어야 한다
article thumbnail
Published 2024. 11. 26. 21:05
Stream API에서 Null 체크 처리하기 JAVA

Java Stream API는 컬렉션을 효율적으로 처리하기 방법이지만, null 값이 포함된 경우 예기치 않은 오류가 발생할 수 있습니다. 특히, NullPointerException을 주의해서 사용해야 합니다. 이번 글에서는 Stream API에서 안전하게 null 체크를 처리하는 방법을 알아보겠습니다.

왜 Null 체크가 필요한가?

Stream 연산 중 null 값이 존재하면 NullPointerException이 발생할 수 있습니다. 예를 들어, 다음 코드를 보면 문제가 생길 가능성이 있습니다

List<String> list = Arrays.asList("A", null, "B");
long count = list.stream()
                 .filter(s -> s.startsWith("A")) // 여기서 NPE 발생 가능
                 .count();

위 코드에서 null 값에 대해 startsWith를 호출하면 NullPointerException이 발생합니다.


Null 체크 방법

Objects::nonNull 사용

Objects::nonNull 메서드는 간단하게 null이 아닌 요소만 필터링할 수 있습니다.

List<String> list = Arrays.asList("A", null, "B");

long count = list.stream()
                 .filter(Objects::nonNull) // null 제외
                 .filter(s -> s.startsWith("A"))
                 .count();

System.out.println(count); // 출력: 1

Optional 사용

Optional은 null 값을 직접 처리할 수 있는 Java 클래스입니다. 특히 스트림 외부에서 null 값을 처리하거나 방어 코드를 작성할 때 유용합니다.

Optional<String> optionalString = Optional.ofNullable(null);

optionalString.ifPresent(value -> System.out.println(value.startsWith("A"))); // 아무 출력 없음

스트림과 함께 사용할 수도 있습니다.

List<Optional<String>> list = Arrays.asList(Optional.of("A"), Optional.empty(), Optional.of("B"));

long count = list.stream()
                 .filter(Optional::isPresent) // 비어 있지 않은 Optional만 필터링
                 .map(Optional::get)         // 값을 꺼냄
                 .filter(s -> s.startsWith("A"))
                 .count();

System.out.println(count); // 출력: 1

특정 객체의 null 체크

스트림에서 처리할 객체 자체가 null일 가능성이 있다면, filter를 사용하여 이를 제외할 수 있습니다.

List<MyObject> list = Arrays.asList(new MyObject("A"), null, new MyObject("B"));

long count = list.stream()
                 .filter(Objects::nonNull) // null 객체 제외
                 .filter(obj -> obj.getName().startsWith("A"))
                 .count();

System.out.println(count); // 출력: 1

여기서 MyObject 클래스는 다음과 같습니다

class MyObject {
    private String name;

    public MyObject(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Null 체크와 성능

filter(Objects::nonNull)을 사용할 때 스트림 내에서 매번 null 체크를 수행하므로, 성능에 영향을 미칠 수 있습니다. 따라서 데이터의 null 가능성을 최소화하거나, 초기 데이터 생성 시점에 null을 처리하는 것이 좋습니다.

 

결론

  1. filter(Objects::nonNull)로 스트림 내 null 값을 안전하게 제외.
  2. Optional을 사용하여 null을 안전하게 처리.
  3. 초기 데이터 준비 단계에서 null 값을 걸러내어 스트림에서의 불필요한 체크를 줄이기.
profile

개발은 재밌어야 한다

@ghyeong

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!