▷ 스트림의 연산
- 중간 연산 : 연산 결과가 스트림인 연산. 스트림에 연속해서 중간 연산할 수 있다.
- 최종 연산 : 연산 결과가 스트림이 아닌 연산. 스트림의 요소를 소모하므로 단 한 번만 가능하다.
중간 연산
1. 스트림 자르기 - skip(), limit()
2. 스트림의 요소 걸러내기 - filter(), distinct()
3. 정렬 - sorted()
4. 변환 - map(), flatMap()
5. 조회 - peek()
- 스트림 자르기 - skip(), limit()
* skip()은 요소를 건너뛰고, limit()는 요소를 제한한다.
IntStream intStream = IntStream.rangeClosed(1,10);
intStream.skip(3).limit(5).forEach(System.out::println);
- 스트림 요소 걸러내기 - filter(), distinct()
* filter()는 주어진 조건에 맞지 않은 요소는 걸러내고, distinct()는 중복된 요소를 제거한다.
IntStream intStream1 = IntStream.of(1,2,2,3,3,3,4,5,5,6);
intStream1.distinct().forEach(System.out::print);//123456
IntStream intStream2 = IntStream.rangeClosed(1,10);//1~10
intStream2.filter(n -> n % 2 == 0).forEach(System.out::print);//246810
- 아래와 같이 여러 번 사용 가능.
intStream2.filter( n -> n % 2 != 0).filter(n -> n % 3 != 0).forEach(System.out::print);
- 스트림 정렬 - sorted()
Stream<String> strStream = Stream.of("dd","aaa","CC","cc","b");
strStream.sorted().forEach(System.out::print);
- 스트림 변환 - map()
* 저장된 요소 중에서 원하는 필드만 뽑아내거나 특정 형태로 변환해야할 때 사용.
Stream<File> fileStream = Stream.of(new File("Ex1.java"), new File("Ex1")
, new File("Ex1.bak"), new File("Ex2.java"), new File("Ex1.txt"));
* map()으로 Stream<File>을 Stream<String>으로 변환
Stream<String> filenameStream = fileStream.map(File::getName);
filenameStream.forEach(System.out::println);
* flatMap() - Stream<T[]>를 Stream<T>로 변환
Stream<String[]> strArrStrm = Stream.of(
new String[]{"abc","def","ghi"},
new String[]{"ABC","GHI","JKLMN"} );
Stream<String> strStrm = strArrStrm.flatMap(Arrays::stream);
- 스트림 조회 - peek()
* 스트림의 요소를 소모하지 않음. 연산과 연산 사이에 올바르게 처리되었는지 확인할 때 사용.
Stream<File> fileStream1 = Stream.of(new File("Ex1.java"), new File("Ex1")
, new File("Ex1.bak"), new File("Ex2.java"), new File("Ex1.txt"));
fileStream1.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);
- mapToInt(), mapToLong(), mapToDouble()
스트림의 요소를 숫자로 변환하는 경우 IntStream과 같은 기본형 스트림으로 변환하는 것이 더 유용할 수 있다.
스트림에 포함된 모든 학생의 성적을 합산해야 한다고 할 때, mapToInt()를 사용해서 Stream<Integer>가 아닌 IntStream타입의 스트림을 생성해서 사용하는 것이 더 효율적이다. 왜냐하면 성적을 더할 때, Integer를 int로 변환할 필요가 없기 때문이다.
Intstream studentScoreStream = studentStream.mapToInt(Student::getTotalScore);
int allTotalScore = studentScoreStream.sum();
IntStream이 숫자를 다루기 위해 제공하는 메서드
- sum()
- average()
- max()
- min()
sum()과 average()를 모두 호출해야 할 때, 매번 스트림을 생성해야 하는 불편함이 있다. 그래서 summaryStatistics()라는 메서드를 제공한다. (LongStream과 DoubleStream도 같은 연산을 지원한다. )
IntSummaryStatistics stat = scoreStream.summaryStatics();
long totalCount = stat.getCount();
long totalScore = stat.getSum();
double avgScore = stat.getAverage();
int minScore = stat.getMin();
int maxScore = stat.getMax();
반대로 IntStream을 Stream<T>로 변환할 때는 mapToObj()를, Stream<Integer>로 변환할 때는 boxed()를 사용한다.
// mapToObj()를 이용해서 IntStream을 Stream<String>으로 변환
IntStream intStream = new Random().ints(1,46);
Stream<String> stringStream = intStream.distinct().limit(6).sorted().mapToObj(i -> i + ",");
stringStream.forEach(System.out::print);
Stream<String> → IntStream 변환할 때, mapToInt(Integer::parseInt)
Stream<Integer> → IntStream 변환할 때, mapToInt(Integer::intValue)
- flatMap() Stream<T[]>를 Stream<T>로 반환
스트림 타입이 Stream<T[]>인 경우, Stream<T>로 다루는 것이 편하다. 이 경우 Stream<T[]>를 Stream<T>로 변환해주는 것이 바로 flatMap()이다.
Stream<String[]> strArrStream = Stream.of(
new String[]{"asd","sdf","dfg"},
new String[]{"zxc","xcv","cvb"}
);
Stream<String> stringStream = strArrStream.flatMap(Arrays::stream);
stringStream.sorted().forEach(System.out::println);
'Language > Java' 카테고리의 다른 글
[Java] 오버로딩 VS 오버라이딩 (0) | 2022.06.14 |
---|---|
[Java]스트림(stream)(3/3) (0) | 2022.06.09 |
[Java]스트림(stream)(1/3) (0) | 2022.06.07 |
[Java] 람다식 (0) | 2022.06.06 |
예외처리(Exception Handling) (0) | 2022.05.27 |