Java Stream

시루봉로·2023년 3월 11일
0

Java 정리

목록 보기
1/2
post-thumbnail

Stream

자바8에서 추가된 스트림(Streams)은 람다를 활용할 수 있는 기술 중 하나이다. 컬렉션 요소에 대한 변환, 필터링, 집계의 처리를 람다식을 사용하여 간결하게 기술할 수 있다. 또한 스트림은 병렬처리(nulti-threading)가 가능하다. 하나의 작업을 둘 이상의 작업으로 잘게 나눠서 동시에 진행하는 것을 병렬 처리(parallel processing)라고 한다. 즉, 스레드를 이용해 많은 요소들을 빠르게 처리할 수 있다.

생성하기: 스트림 인스턴스 생성
가공하기: 필터링 및 매핑을 통해 원하는 결과를 만들어가는 중간 작업
결과 만들기: 최종적으로 결과를 만들어내는 작업

생성하기

Stream은 List와 Map 같은 컬렉션에 대해 Stream() 메서드를 호출함으로써 구할 수 있다.

// List에서 Stream 구하기
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> s1 = list.stream();

// Set에서 Stream 구하기
Set<String> set = new HashSet<>();
Stream<String> s2 = set.stream();

// Map의 경우 entrySet() 메서드 등에서 Stream 구하기
Map<String, String> map = new HashMap<>();
Stream<Map.Entry<String, String>> s3 = map.entrySet().stream();

또한 Stream.of() 메서드로 배열이나 고정 요소에서 Stream을 구할 수 있다. 또한 배열에서 stream을 생성할 경우에는 Arrays.stream() 메서드를 사용할 수 있다. 이러한 경우 int형, long형, double형 배열을 인수로 호출하면 IntStream, LongStream, DoubleStream을 구할 수 있다.

// 배열에서 stream 생성
String [] arr = {"a", "b", "c", "d"};
Stream<String> s1 = Stream.of(arr);

// 고정 요소에서 stream 생성
Stream<String> s2 = Stream.of("a", "b", "c", "d");

// Int형 배열은 IntStream
int[] arr2= {1, 2, 3};
IntStream s3 = Arrays.stream(arr2);

가공하기

생성된 스트림은 다음과 같이 메서드 체인으로 처리할 수 있다.

List<String> list = {"a", "b", "c", "d"};

list.stream()
	.filter(s -> s.startsWith("a"))    // 선두가 a로 시작되는 것만
    .map(s -> s.toUpperCase))          // 각 요소를 대문자로 변환
    .sorted((a, b) -> a.length() - b.length()) // 문자 수가 작은 순으로 정렬
    .forEach(System.out::println);     // 표준 출력에 사용

아래는 자주 사용하는 메서드 목록이다.

of: 지정된 값으로부터 Stream을 생성한다.
count: Stream의 요소 수를 반환한다.
distinct: Stream 요소의 중복을 배제한다.
forEach: Stream의 요소에 대해 임의의 처리를 한다.
filter: Stream의 요소를 지정하는 조건으로 필터링한다.
concat: 2개의 Stream을 연결한다.
map: Stream의 요소를 반환한다.
mapToDouble: Stream의 요소를 double형으로 변환하고 DoubleStream을 반환한다.
mapToInt: Stream의 요소를 int형으로 변환하고 IntStream을 반환한다.
mapToLong: Stream의 요소를 long형으로 변환하고 LongStream을 반환한다.
flatMap: Stream의 요소를 변환하고 요소를 정리한다.
allMatch: Stream의 모든 요소가 조건을 충족하는지 알아본다.
anyMatch: Stream 요소가 1개라도 조건을 충족시키는지 알아본다.
noneMatch: Stream 요소가 모든 조건을 충족시키지 않는지 알아본다.
reduce: Stream 요소를 집계한다.
sum: Stream 요소를 합계한다.
sorted: Stream 요소를 정렬한다.
collect: Stream 요소의 집계 처리와 컬렉션으로 변환 등을 한다.
toArray: Stream을 배열로 변환한다.
iterate: 무한값을 반환하는 Stream을 생성한다.
limit: 앞에서 지정한 건수 만큼 반환한다.
parallelStream: 순서대로 처리하는 Stream에서 병렬 처리할 수 있는 Stream을 구한다.
sequential: 병렬 처리가 가능한 Stream에서 순서대로 처리할 Stream을 구한다.

결과 만들기

Stream은 메서드 체인으로 다양한 처리를 연쇄적으로 기술할 수 있지만, count(), forEach(), reduce() 등을 호출하면 거기서 메서드 체인을 종료하는 메서드가 있다. 이들 메서드를 종단 메서드라고 한다. 종단 메서드를 호출하면 거기서 메서드 체인을 종료할 뿐 아니라 그 스트림은 닫히면서 더 이상 사용할 수 없게 된다. 이런 경우는 필요에 따라 그 때마다 스트림을 생성해야 한다.

Stream<String> stream = Stream.of("a", "b", "c", "d");

// Stream 요소를 표준 출력에 출력
stream.forEach(System.out::println);

// 다시 호출하면 IllegalStateException이 발생한다.
stream.forEach(System.out::println);

참고 자료

본 글은 아래 링크를 기반으로 정리하였습니다.

profile
안녕하세요.

0개의 댓글