[기본 개념] 9 | (2.2) 스트림 중간 연산
1 스트림이란?
2 스트림 만들기
3> 스트림의 중간연산
4> Optional<T>와 OptionalInt
5 스트림의 최종연산
6 collect( )
7 Collector 구현하기
8 스트림의 변환
3. 스트림의 중간연산
스트림 자르기 - skip( ), limit( )
skip( )은 요소를 건너뛰고, limit( )는 요소의 개수를 제한한다.
IntStream intStream = IntStream.rangeClosed(1, 10) ; // 1 ~ 10의 요소를 가진 스트림
intStream.skip(3).limit(5).forEach(System.out :: println) ; // 45678
스트림의 요소 걸러내기 - filter( ), distinct( )
distinct( )는 스트림에서 중복된 요소들을 제거하고, filter( )은 주어진 조건에 맞지 않는 요소를 걸러낸다.
IntStream intStream = IntStream.of(1, 2, 2, 3, 3, 3, 4, 5, 5, 6) ;
intStream.distinct( ).forEach(System.out :: println) ; // 123456
IntStream intStream = IntStream.rangeClosed(1, 10) ;
intStream.filter(i -> i % 2 == 0).forEach(System.out :: println) ; // 246810
정렬 - sorted( )
sorted( )는 지정된 Comparator로 스트림을 정렬하는 데, 대신 int값을 반환하는 람다식을 사용해도 된다. Comparator를 지정하지 않으면 스트림 요소의 기본 정렬 기준으로 정렬한다.
Stream<String> strStream = Stream.of("dd", "aaa", "CC", "cc", "b") ;
strStream.sorted( ).forEach(System.out :: println) ; // CCaaabccdd
정렬에 사용되는 기본적인 메서드는 comparing( )이다. 비교대상이 기본형이면 comparing( )대신 comparingInt, comparingDouble, ComparingLong을 사용하여 오토박싱&언박싱과정을 줄여 효율적이게 하자.
정렬조건을 추가할 때는 thenComparing( )을 사용한다.
예를 들어 학생 스트림을 반별, 성적순, 이름순으로 정렬하여 출력하려면 다음과 같이 한다.
studentStream.sorted(Comparator.comparing(Student :: getBan)
.thenComparing(Student :: getTotalScore)
.thenComparing(Student :: getName))
.forEach(System.out :: println) ;
변환 - map( )
스트림의 요소에 저장된 값 중에서 원하는 필드만 뽑아내거나 특정 형태로 변환해야 할 때 map( )을 사용한다.
예를 들어 File의 스트림에서 파일의 이름(String)만 뽑아서 출력하고 싶을 때, 아래와 같이 map( )을 사용할 수 있다. 그리고 map( )도 중간 연산이고, filter( )처럼 하나의 스트림에 여러 번 적용할 수 있다.
fileStream.map(File :: getName) // Stream<File> -> Stream<String>
.filter(s -> s.indexOf('.') != -1) // 확장자가 없는 것은 제외
.map(s -> s.substring(s.indexOf('.') + 1)) // Stream<String> -> Stream<String>
.map(String :: toUpperCase) // 모두 대문자로 전환
.distinct( ) // 중복 제거
.forEach(System.out :: print) ; // JAVATXT
조회 - peek( )
연산과 연산 사이에 올바르게 처리되었는지 확인하고 싶을 때 peek( )를 사용한다. 스트림의 요소를 소모하지 않으므로 여러 번 끼워넣어도 괜찮다.
fileStream.map(File :: getName) // Stream<File> -> Stream<String>
.filter(s -> s.indexOf('.') != -1) // 확장자가 없는 것은 제외
.peek(s -> System.out.printf("filename = %s%n", s)) // 파일명 출력
.map(s -> s.substring(s.indexOf('.') + 1)) // 확장자만 추출
.peek(s -> System.out.printf("extension = %s%n", s)) // 확장자를 출력
.forEach(System.out :: print) ;
flatMap( ) - Stream<T[ ]>를 Stream<T>로 변환
스트림의 요소가 배열이거나 map( )의 연산결과가 배열인 경우, Stream<T>로 다루는 것이 편리할 때 map( )대신 flatMap( )을 사용하면 된다.
Stream<String[ ]> strArrStrm = Stream.of {
new String[ ]{"abc", "def", "ghi"},
new String[ ]{"ABC", "GHI", "JKLMN"}
} ;
Stream<String> strStrm = strArrStrm.flatMap(Arrays :: stream) ;
이러면 각 요소의 문자열들을 합쳐서 문자열이 요소인 스트림 Stream<String>으로 만들 수 있다.
출처 | Java의 정석 (남궁 성)
'💠프로그래밍 언어 > Java' 카테고리의 다른 글
[Spring] View 를 처리하는 방법들 (Static, Template, API) (1) | 2024.12.20 |
---|---|
[Spring] 스프링 프로젝트 생성, 라이브러리, 빌드하기 (0) | 2024.12.20 |
[기본 개념] 9 | (2.1) 스트림 (0) | 2022.01.26 |
[기본 개념] 9 | (1.2) Java.util.funcion 패키지, Function 합성, Predicate 결합, 메서드 참조 (0) | 2022.01.26 |
[기본 개념] 9 | (1.1) 람다식, 람다식 인터페이스 (0) | 2022.01.25 |