본문 바로가기

Java 길찾기/이것이 자바다

[Java] 스트림의 종류

자바 8 부터 새로 추가된 java.util.stream 패키지에는 스트림(stream) API들이 포진하고 있다. 패키지 내용을 보면 BaseStream 인터페이스를 부모로 해서 자식 인터페이스들이 상속 관계를 이루고 있다.

 

BaseStream 인터페이스에는 모든 스트림에서 사용할 수 있는 공통 메소드들이 정의되어 있을 뿐 코드에서 직접적으로 사용되지는 않는다. 하위 스트림인 Stream, IntStream, LongStream, DoubleStream이 직접적으로 이용되는 스트림인데, Stream은 객체 요소를 처리하는 스트림이고, IntStream, LongStream, DoubleStream은 각각 기본 타입인 int, long, double 요소를 처리하는 스트림이다. 이 스트림 인터페이스의 구현 객체는 다양한 소스로부터 얻을 수 있다. 주로 컬렉션과 배열에서 얻지만, 다음과 같은 소스로부터 스트림 구현 객체를 얻을 수도 있다.

리턴 타입 메소드(매개 변수) 소스
Stream<T> java.util.Collection.steram()
java.util.Collection.parallelStream()
컬렉션
Stream<T>
IntStream
LongStream
DoubleStream
Arrays.stream(T[]), Stream.of(T[])
Arrays.stream(int[]), IntStream.of(int[])
Arrays.stream(long[]), LongStream.of(long[])
Arrays.stream(double[]), DoubleStream.of(double[])
배열
IntStream IntStream.range(int, int)
intStream.rangeClosed(int, int)
int 범위
LongStream LongStream.range(long, long)
LongStream.rangeClosed(long, long)
long 범위
Stream<Path> Files.find(Path, int, BiPredicate, FileVisitOption)
Files.list(Path)
디렉토리
Stream<String> Files.lines(Path, Charset)
BufferedReader.lines()
파일
DoubleStream
IntStream
LongStream
Random.doubles(...)
Random.ints()
Random.longs()
랜덤 수

 

컬렉션으로부터 스트림 얻기

다음 예제는 List<Student> 컬렉션에서 Stream<Student>를 얻어내고 요소를 콘솔에 출력한다.

// FromCollectionExample.java -- 컬렉션으로부터 스트림 얻기
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class FromCollectionExample {
    public static void main(String[] args) {
        List<Student> studentList = Arrays.asList(
                new Student("홍길동", 10),
                new Student("김자바", 20),
                new Student("오징어", 30)
        );
        
        Stream<Student> stream = streamList.stream();
        stream.forEach(s -> System.out.println(s.getName()));
    }
}
// Student.java -- 학생 클래스
public class Student {
    private String name;
    private int score;
    
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    
    public String getName() { return name; }
    public int getScore() { return score; }
}

 

배열로부터 스트림 얻기

다음 예제는 String[]과 int[] 배열로부터 스트림을 얻어내고 콘솔에 출력한다.

// FromArrayExample.java -- 배열로부터 스트림 얻기
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class FromArrayExample {
    public static void main(String[] args) {
        String[] strArray = { "홍길동", "김자바", "오징어"};
        Stream<String> strStream = Arrays.stream(strArray);
        strStream.forEach( a -> System.out.println(a + ",") );
        System.out.println();
        
        int[] intArray = { 1, 2, 3, 4, 5 };
        IntStream intStream = Arrays.stream(intArray);
        intStream.forEach( a -> System.out.println(a + ",") );
        System.out.println();
    }
}

 

숫자 범위로부터 스트림 얻기

다음은 1부터 100까지의 합을 구하기 위해 IntStream의 rangeClosed() 메소드를 이용하였다. rangeClosed()는 첫 번째 매개값에서 두 번째 매개값까지 순차적으로 제공하는 IntStream을 리턴한다. IntStream의 또 다른 range() 메소드도 동일한 IntStream을 리턴하는데, 두 번째 매개값은 포함하지 않는다.

// FromIntRangeExample.java -- 정수 범위를 소스로 하는 스트림
import java.util.stream.IntStream;

public class FromIntRangeExample {
    public static int sum;
    
    public static void main(String[] args) {
        IntStream stream = IntStream.rangeClosed(1, 100);
        stream.forEach( a -> sum += a );
        System.out.println("총합: " + sum);
    }
}

 

파일로부터 스트림 얻기

다음 예제는 Files의 정적 메소드인 lines()와 BufferedReader의 lines() 메소드를 이용하여 문자 파일의 내용을 스트림을 통해 행 단위로 읽고 콘솔에 출력한다.

// FromFileContentExample.java -- 파일 내용을 소스로 하는 스트림
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IoException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class FromFileContentExample {
    public static void main(String[] args) throws IOExeption {
        Path path = Paths.get("src/sec02/stream_kind/linedata.txt");
        Stream<String> stream;
        
        // Files.lines() 메소드 이용
        stream = Files.lines(path, Charset.defaultCharset());
        stream.forEach( System.out :: println );
        System.out.println();
        
        // BufferedReader의 lines() 메소드 이용
        File file = path.toFile();
        FileReader fileReader = new FileReader(file);
        BufferedReader br = new BufferedReader(fileReader);
        stream = br.lines();
        stream.forEach( System.out :: pirntln );
    }
}

 

디렉토리로부터 스트림 얻기

다음 예제는 Files의 정적 메소드인 list()를 이용해서 디렉토리의 내용(서브 디렉토리 또는 파일 목록)을 스트림을 통해 읽고 콘솔에 출력한다.

// FromDirectoryExample.java -- 디렉토리 내용을 소스로 하는 스트림
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Pahts;
import java.util.stream.Stream;

public class FromDirectoryExample {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("3:/JavaProgramming/source");
        Stream<Path> stream = Files.list(path);
        stream.forEach( p -> System.out.println(p.getFileName()) );
    }
}