Language/Java

15-2. 스트림의 중간 연산

리져니 2021. 8. 5. 13:41

스트림 자르기: skip(), limit()

예제

IntStream intStream = IntStream.rangeClosed(1,10); 	// 1 2 3 4 5 6 7 8 9 10 요소를 가진 스트림
intStream.skip(3).limit(5).forEach(System.out::print);	// 4 5 6 7 8

 

스트림 요소 걸러내기: filter(), distinct()

예제

IntStream intStream = IntStream.of(1,2,2,3,3,3,4,5,5,6);
intStream.distinct().forEach(System.out::print);	// 123456

IntStream intStream = IntStream.rangeClosed(1,10);		// 12345678910
intStream.filter(i -> i%2 ==0).forEach(System.out::print);	// 246810

 

정렬: sorted()

sorted()는 지정된 Comparator로 스트림을 정렬하는데, Comparator대신 int값을 반환하는 람다식도 가능하다.

Comparator를 지정하지 않으면 기본 정렬 기준으로 정렬한다.

 

예제

Strema<String> strStream = Stream.of("dd", "aaa", "CC", "cc", "b");
strStream.sorted().forEach(System.out::print);	// CCaaabccdd

 

문자열 스트림을 정렬하는 다양한 방법

정렬에 사용되는 가장 기본적인 메서드는 comparing()이다.

스트림의 요소가 comparable을 구현한 경우, 매개변수 하나짜리를 이용하고, 그렇지 않은 경우에는  추가적인 매개변수로 정렬기준을 따로 지정해주어야한다.

 

비교대상이 기본형인 경우에는 아래의 메서드를 사용하면 오토박싱와 언박싱과정이 없어서 더 효율적이다.

 

정렬 조건을 추가할 때는 thenComparing()을 사용한다.

예제

studentStream.sorted(Comparator.comparing(Student::getBan)
					.thenComparing(Student::getTotalScore)
                    .thenComparing(Student::getName)
                    .forEach(System.out::println);

 

변환: map()

스트림의 요소에 저장된 값 중에서 원하는 필드만 뽑아내거나 특정 형태로 변환할때 사용.

연산결과는 String을 요소로 하는 스트림이며, 하나의 스트림에 여러번 적용할 수있다.

 

예제

// 파일 스트림 생성
Stream<File> fileStream = Stream.of(new File("Ex1.java"), new File("Ex1"), new File("Ex1.bak");

// map()으로 Stream<File>을 Strema<String>으로 변환
Stream<String> filenameStream = fileStream.map(File::getName);

// 파일이름 스트림의 요소출력
filenameStream.forEach(System.out::println);

 

기본형 스트림으로 변환: mapToInt(), mapToLong(), mapToDouble()

Stream<T>타입의 스트림을 기본형 스트림으로 변환할때 사용

예제

IntStream studentScoreStream = studentStream.mapToInt(Student::getTotalScore);
int allTotalScore = studentScoreStream.sum();	// int sum();

Stream<Integer>가 아닌 IntStream타입의 스트림을 생성해서 사용하는 것이 더 효율적이다.(integer를 int로 변환할 필요가 없기 때문)

 

타입 메서드 설명
int sum() 스트림의 모든 요소의 총합
OptionalDouble average() 스트림의 모든 요소의 총합 평균
OptionalInt max() 스트림의 요소 중 제일 큰 값
OptionalInt min() 스트림의 요소 중 제일 작은 값

count()만 지원하는 Stream와 다르게 IntStream과 같은 기본형 스트림은 숫자를 다루는데 편리한 메서드르 제공한다.

이 메서드들은 최종연산이기 때문에 호출 후에 스트림이 닫힌다.

하나의 스트림에 sum()과 average()를 연속해서 호출할수 없다. 두 메서드를 모두 호출해야 할 때는 스트림을 또 생성해야 하는 불편함이 있다.

이런 경우에는 summaryStatistics()라는 메서드를 사용하면 된다.

IntSummaryStatistics stat = scoreStrem.summaryStatistics();
long totalCount = stat.getCount();
long totalScore = stat.getSum();
double avgScore = stat.getAverage();
int minScore = stat.getMin();
int maxScore = stat.getMax();

 

 

 

Stream<T[]>를 Stream<T>로 변환: flatMap()

스트림의 요소가 배열이거나 map()의 연산결과가 배열인 경우, Stream<T>로 다루는 것이 더 편리할 때가 있다. 그럴때 map()대신 flatMap()을 사용한다.

 

예시

Stream<String[]> strArrStrm = Stream.of(
				new String[] {"abc", "def", "ghi" }, new String[] {"ABC", "GHI", "KJM" });
                                        
Stream<String> strStrm = strArrStrm.flatMap(Arrays::stream);
strStrm.map(String::toLowerCase)	// 스트림의 요소를 모두 소문자로 변경
		.distinct()					// 중복 제거
        .sorted()					// 정렬
        .forEach(System.out::println);

 

조회: peek()

스트림의 요소를 소비하지 않고 엿보는 방법. (중간 작업 결과를 확인할때 주로 쓴다-디버깅 용도)

forEach()와 다르게 스트림의 요소를 소모하지 않으므로 연산 사이에 여러번 끼워 넣어도 문제되지 않는다.

 

예제

fileStream.map(File::getName)
			.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::println);

 

728x90

'Language > Java' 카테고리의 다른 글

15-4(1). 스트림의 최종 연산  (0) 2021.08.05
15-3. Optional  (0) 2021.08.05
15-1. 스트림 만들기  (0) 2021.08.04
15. 스트림(stream)  (0) 2021.08.04
14. java.util.function 패키지  (0) 2021.08.04