반응형
스트림(Stream)
스트림은 배열, 컬렉션, 파일 등 여러 데이터들을 다루는 자료형에서 데이터를 하나씩 참조하여 처리 가능한 기능을 말한다. 람다를 사용할 수 있는 기술이다. 반복문이나 iterator를 사용하지 않아도 된다. JDK 1.8부터 나왔다.
이를 통해 for문의 사용을 줄여서 코드를 간결하게 할 수 있다.
특징으로는
- 원본 데이터를 사용하지만 변경은 불가능하다.
- 일회용으로 사용하므로 처리 후 재사용이 불가능하다.
- 내부적으로 반복 및 병렬처리가 가능하다.
- 기본 데이터을 처리하기 위한 래퍼 스트림(Int,Double,LongStream)도 지원한다.
Stream은 크게 Stream 생성, 중개연산, 최종연산의 3단계로 진행된다.
데이터소스객체.Stream생성().중개연산().최종연산(); 이런식으로 쓰인다.
스트림 객체는 최종연산을 하면 더 이상 스트림연산을 할 수 없고 종료가 된다. 그 객체로 더 하려고 하면 오류가 뜬다.
각 단계의 자주 쓰이는 것들을 알아보자.
스트림 생성
종류 | 사용 예시 | 설명 |
배열 스트림 | Stream s1 = Arrays.stream(arr); | arr은 위에 선언된 배열이라고 가정 |
컬렉션 스트림 | Steram s2 = l1.stream(); | l1은 위에서 선언된 컬렉션이라고 가정 |
스트림 builder | Stream b1 = Stream.builder().add(1).add("gef").add(7).build(); | add로 원하는 값을 넣고 build로 스트림을 생성 |
스트림 generate |
Stream g1 = Stream.generate( () -> "abc" ).limit(3);
|
람다를 통해 값을 넣은 스트림 생성 limit은 옆 행동을 반복한다는 뜻이다. 즉, 예시는 "abc"가 3개 있는 스트림을 생성한다. |
스트림 iterate | Stream i1 = Stream.iterate(5, n -> n * 2).limit(4); | 5는 초기값이고 람다식을 한번씩 적용해서 4개의 값이 들어있는 스트림을 생성한다. 예시는 5,10,20,40이 있는 스트림을 생성한다. |
기본 타입 스트림 | IntStream s3 = Intstream.range(1,5); | range는 연속적인 숫자를 만드는 함수다. 예시는 1,2,3,4가 있는 스트림을 생성한다. |
기본 데이터형을 다룰때는 Stream<Integer> list1 = list.stream();같이 래퍼클래스로 해준다.
중개연산
종류 | 사용 예시 | 설명 |
Filtering |
IntStream s1 = IntStream.range(1, 10).
filter(n -> n % 2 == 0); |
filter는 어떤 조건을 줘서 참인 요소들을 추출하는 것이다. 예시는 1~9중 짝수인걸 추출한다. ** distinct()라고 중복을 지워주는 메소드도 있다. ** |
Mapping | IntStream s2 = IntStream.range(1, 10).map(n -> n + 1); | map은 map 안의 연산을 요소별로 수행하는 것이다. 예시는 1~9에 1을 더한 스트림을 만든다. ** flatMap()라고 스트림요소가 배열인 경우 주어진 명령문을 적용한 새로운 스트림을 반환한다. ** |
Sorting | s3.sorted(); | sort는 stream을 정렬하는 것이다. |
Splitting | s4.limit(3); // (5,1,2,4,6) -> (5,1,2)반환 s4.skip(3); // (5,1,2,4,6) -> (4,6,)반환 |
limit()은 스트림에서 limit에 들어가는 수만큼의 새로운 스트림을 반환한다. skip()은 스트림의 첫 요소부터 skip에 들어가는 수를 제외한 새로운 스트림을 반환한다. |
최종연산
종류 | 사용 예시 | 설명 |
Sum | int sum = IntStream.range(1, 5).sum(); | 예시는 1~4의 값을 더하는 최종연산이다. |
Average | double average = IntStream.range(1, 5).average().getAsDouble(); | 예시는 1~4의 값의 평균을 구하는 연산이다. |
min | int min = IntStream.range(1, 5).min().getAsInt(); | Stream 값중 최솟값을 구하는 연산이다. |
max | int max = IntStream.range(1, 5).max().getAsInt(); | Stream 값중 최댓값을 구하는 연산이다. |
reduce | s1.reduce((x, y) -> x + y).get(); | map이랑 유사해 보이지만, reduce는 연쇄적으로 해서 데이터를 뽑아내는 연산이다. |
anyMatch | s1.anyMatch(n -> n % 2 == 1); | 스트림의 일부 요소가 특정 조건 만족시 true 반환 |
allMatch | s1.allMatch(n -> n % 2 == 1); | 스트림의 모든 요소가 특정 조건 만족시 true 반환 |
noneMatch | s1.noneMatch(n -> n % 2 == 1); | 스트림의 모든 요소가 특정 조건 불만족시 true 반환 |
findFirst | s1.findFirst(); | 스트림 첫 요소 반환 |
forEach | s1.forEach(System.out::println); s1.forEach(num -> System.out.println("num = " + num));
|
해당 스트림 각 요소를 출력하는 연산이다. 람다식으로 출력형식을 정할 수도 있다. |
** 입출력에서 스트림은 자바에서 입출력을 위해 두 대상을 연결하여 데이터를 송/수신하는데 사용되는 연결통로이다. 중간에 끊김없이 연속적으로 데이터를 송수신한다.
Optional 클래스
스트림 결과값을 반환받을 때 사용가능한 참조형 데이터 타입이다.
Null값으로 인한 예외를 회피할 수 있다. 특정 클래스가 참조변수인 경우에는 NullPointerException이 발생할 수 있어서 Null값에 대한 예외 처리를 해줘야한다.
Optional 클래스는 모든 타입의 참조변수를 저장할 수 있고, 스트림과 비슷하게 기본 데이터형을 처리할 수 있는 래퍼클래스를 지원한다.
반응형