Java 9의 Optional.stream() 메서드 소개
Java 9에서는 Optional 클래스에 stream() 메서드가 새롭게 추가되면서 기능이 한층 강화되었습니다. 이 메서드는 Optional 요소로 이루어진 Stream을 실제 값이 존재하는 요소만 담긴 Stream으로 변환할 때 유용하게 사용됩니다.
동작 방식은 매우 직관적입니다. Optional 객체에 값이 존재하면 그 값을 포함하는 Stream을 반환하고, 값이 없다면(빈 Optional이라면) 빈 Stream(empty stream)을 반환합니다. 덕분에 null 체크나 isPresent() 검사 없이도 스트림 파이프라인에서 빈 Optional을 자연스럽게 걸러낼 수 있습니다.
문법(Syntax)
public Stream<T> stream()
반환 타입은 Stream<T>이며, 값이 있으면 요소 1개짜리 스트림, 값이 없으면 요소 0개짜리 스트림을 반환합니다.
예제 코드
아래 예제는 Java 8 방식과 Java 9 방식을 비교하여 보여줍니다. 두 방식 모두 빈 Optional을 제거하고 실제 값만 추출하지만, Java 9의 Optional::stream을 사용하면 훨씬 간결한 코드를 작성할 수 있습니다.
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamMethodTest {
public static void main(String[] args) {
List<Optional<String>> list = Arrays.asList(
Optional.empty(),
Optional.of("TutorialsPoint"),
Optional.empty(),
Optional.of("Tutorix"));
// Java 8 방식: Optional이 비어있지 않으면 값을 스트림으로 꺼내고,
// 비어있다면 빈 스트림을 반환합니다.
List<String> filteredListJava8 = list.stream()
.flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
.collect(Collectors.toList());
// Java 9 방식: Optional::stream 메서드는 값이 존재하면 요소 1개짜리,
// 존재하지 않으면 요소 0개짜리 스트림을 반환합니다.
List<String> filteredListJava9 = list.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
System.out.println(filteredListJava8);
System.out.println(filteredListJava9);
}
}실행 결과
[TutorialsPoint, Tutorix] [TutorialsPoint, Tutorix]
핵심 정리
- 간결성 향상: Java 8에서는 삼항 연산자와
Stream.of(),Stream.empty()를 조합해야 했지만, Java 9에서는flatMap(Optional::stream)한 줄로 동일한 결과를 얻을 수 있습니다. - 가독성 개선: 메서드 참조(
Optional::stream)를 활용하면 의도가 명확하게 드러나 코드 가독성이 크게 좋아집니다. - 안전한 값 필터링: 빈 Optional을 별도의 조건문 없이 스트림 파이프라인 안에서 자동으로 제거하므로, NullPointerException 발생 위험도 줄어듭니다.
Optional 컬렉션을 다루는 코드를 작성할 때는 Java 9 이상 환경이라면 stream() 메서드를 적극적으로 활용하는 것이 좋습니다.