자바의 스트림(Stream)은 컬렉션, 배열, 파일 등의 데이터를 다룰 때 매우 강력한 기능을 제공합니다.

이번 글에서는 리소스로부터 스트림을 얻는 방법, 요소를 필터링하는 방법, 그리고 요소를 변환하는 방법(매핑) 에 대해 다룹니다.


🔹 1. 리소스로부터 스트림 얻기

스트림은 꼭 컬렉션(Collection)에서만 생성할 수 있는 것이 아닙니다. 다양한 리소스(데이터를 저장하는 객체 또는 파일)에서 스트림을 생성할 수 있습니다.

📌 스트림 인터페이스 개요

자바의 스트림 패키지에는 BaseStream 인터페이스가 있고, 이를 상속하여 여러 스트림이 만들어집니다.

스트림 타입 설명
Stream<T> 객체 요소를 처리하는 스트림
IntStream int 기본 타입 요소가 흘러가는 스트림
LongStream long 기본 타입 요소가 흘러가는 스트림
DoubleStream double 기본 타입 요소가 흘러가는 스트림

📌 리소스별 스트림 생성 방법

자바에서 스트림을 생성할 수 있는 대표적인 리소스는 다음과 같습니다.

리소스 스트림 생성 방법
컬렉션(Collection) stream(), parallelStream()
배열(Array) Arrays.stream(array), Stream.of(array)
숫자 범위 IntStream.range(start, end), LongStream.rangeClosed(start, end)
파일(File) Files.lines(path, charset) (한 줄씩 읽어서 스트림 생성)
랜덤(Random) 값 new Random().ints(), new Random().doubles()

📌 컬렉션에서 스트림 얻기

List<String> list = List.of("Java", "Python", "C++", "Java");
Stream<String> stream = list.stream(); // 순차 스트림
Stream<String> parallelStream = list.parallelStream(); // 병렬 스트림

📌 배열에서 스트림 얻기

String[] array = {"Java", "Python", "C++"};
Stream<String> stream1 = Arrays.stream(array);
Stream<String> stream2 = Stream.of(array);

📌 숫자 범위에서 스트림 얻기

IntStream intStream = IntStream.range(1, 10); // 1~9 (끝 포함 X)
IntStream intStreamClosed = IntStream.rangeClosed(1, 10); // 1~10 (끝 포함 O)

📌 파일에서 스트림 얻기

Path path = Paths.get("data.txt");
Stream<String> fileStream = Files.lines(path, StandardCharsets.UTF_8);
fileStream.forEach(System.out::println);

🔹 2. 요소 걸러내기(필터링)

필터링은 스트림에서 특정 조건을 만족하는 요소만 걸러내는 중간 처리 작업입니다.

📌 필터링 메소드

메소드 설명
distinct() 중복 제거
filter(Predicate<T> predicate) 특정 조건에 맞는 요소만 선택

📌 예제 1: 중복 제거

List<String> names = List.of("Java", "Python", "Java", "C++", "Python");
names.stream()
     .distinct()
     .forEach(System.out::println); 
// 결과: Java, Python, C++

📌 예제 2: 특정 조건의 요소 필터링

List<String> names = List.of("신용권", "홍길동", "신사임당", "이순신");
names.stream()
     .filter(name -> name.startsWith("신"))
     .forEach(System.out::println);
// 결과: 신용권, 신사임당

📌 예제 3: 숫자 필터링

IntStream.rangeClosed(1, 10)
         .filter(n -> n % 2 == 0) // 짝수만 선택
         .forEach(System.out::println);
// 결과: 2, 4, 6, 8, 10

🔹 3. 요소 변환(매핑)

맵핑은 스트림의 요소를 변환하여 새로운 스트림을 만드는 과정입니다.

📌 변환 메소드

메소드 설명
map(Function<T, R> mapper) 객체 -> 다른 객체 변환
mapToInt(ToIntFunction<T> mapper) 객체 -> int 변환
mapToLong(ToLongFunction<T> mapper) 객체 -> long 변환
mapToDouble(ToDoubleFunction<T> mapper) 객체 -> double 변환
flatMap(Function<T, Stream<R>> mapper) 하나의 요소 -> 여러 개의 요소 변환

📌 예제 1: 객체를 특정 값으로 변환

 
class Student {
    String name;
    int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    public int getScore() {
        return score;
    }
}

List<Student> students = List.of(
    new Student("홍길동", 85),
    new Student("이순신", 90),
    new Student("강감찬", 80)
);

students.stream()
        .mapToInt(Student::getScore) // 객체 -> int 변환
        .forEach(System.out::println);
// 결과: 85, 90, 80

📌 예제 2: 문자열을 단어 단위로 변환 (flatMap)

List<String> sentences = List.of("I am a Java Developer", "Learning Java Streams");

sentences.stream()
         .flatMap(sentence -> Arrays.stream(sentence.split(" "))) // 문장을 단어로 분리
         .forEach(System.out::println);
// 결과: I, am, a, Java, Developer, Learning, Java, Streams

🎯 정리

 

기능
메소드 설명
스트림 생성 stream() 컬렉션에서 스트림 생성
Arrays.stream() 배열에서 스트림 생성
Files.lines() 파일에서 스트림 생성
필터링 distinct() 중복 제거
filter() 조건에 맞는 요소만 선택
변환(매핑) map() 요소를 변환하여 새로운 스트림 생성
flatMap() 하나의 요소를 여러 개로 변환

 

자바 스트림을 활용하면 데이터를 보다 효율적으로 처리할 수 있습니다.

특히 컬렉션, 배열, 파일 등의 데이터를 스트림으로 변환하여 필터링 및 변환하는 과정을 잘 이해하면 더 강력한 프로그래밍이 가능합니다.

 

 

 

 

 

 

참조:
이것이 자바다 _ 신용권

 

 

 

+ Recent posts