-
[Java] 스트림의 중간연산Java 2022. 2. 9. 00:01
이전 시간에 스트림의 생성에 대해서 알아보았습니다
https://junuuu.tistory.com/78?category=968252
스트림은 아래와 같은 주기를 가집니다.
1. 스트림 생성
2. 중간 연산 (0~ n번)
3. 최종 연산 (0~1번)
오늘은 중간 연산에 대해 알아보겠습니다
스트림 자르기
Stream<T> skip(long n) Stream<T> limit(long maxSize) IntStream intStream = intStream.rangeClosed(1, 10) ; // 1~10의 요소를 가진 스트림 생성 intStream.skip(3).limit(5).forEach(System.out::print); //45678
skip() 과 limit() 은 스트림의 일부를 잘라낼 때 사용합니다.
skip(3)은 3개의 요소를 건너뛰고, limit(5)는 스트림의 요소를 5개 로제 한합니다.
intStream은 1~10 요소를 가지며 여기서 3개의 요소를 건너뛰면 4~10 5개를 잘라내면 45678이 됩니다.
스트림의 요소 걸러내기
Stream<T> filter(Predicate<? super T> predicate) Stream<T> 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); // 1~10의 요소를 가진 스트림 intStream.filter( i -> i%2 ==0).forEach(System.out::print); //246810 //동일한 결과 제공 intStream.filter( i -> i%2 ==0 && i%3 != 0).forEach(System.out::print); //157 intStream.filter( i -> i%2 ==0).filter(i -> i%3 !=0).forEach(System.out::print); //246810
distinct()는 스트림에서 중복된 요소를 제거합니다.
filter()는 매개변수로 Predicate 함수형 인터페이스를 필요로 하는데, 연산 결과가 boolean인 람다식을 사용해도 됩니다.
또한 filter()를 다른 조건으로 여러 번 사용할 수 있습니다.
스트림의 정렬
Stream<T> sorted() Stream<T> sorted(Comparator<? super T> comparator) Stream<String> strStream = Stream.of("dd", "aaa", "CC", "c", "b"); strStream.sorted().forEach(System.out::print); //CCaaabccdd //출력결과 CCaaabccdd strStream.sorted() strStream.sorted(Comparator.naturalOrder()) strStream.sorted(s1,s2) -> s1.compareTo(s2)); //람다식도 가능 strStream.sorted(String::compareTo); //람다식을 메소드 참조로 변환 //출력결과 ddccbaaaCC strStream.sorted(Comparator.reverseOrder()) //역순 //출력결과 bddCCccaaa strStream.sorted(Comparator.comparing(String::length)) //길이순 정렬
sorted()는 지정된 Comparator로 스트림을 정렬하는데, 반환형이 int인 람다식을 사용해도 됩니다.
Comparator를 지정하지 않으면 기본 정렬 기준으로 정렬합니다.
이때 아래와 같이 comparing()으로 정렬 기준을 제공할 수 있습니다.
//반별로 정렬 studentStream.sorted(Comparator.comparing(Student::getBan)).forEach(System.out::println); //추가 정렬 기준을 제공할 때는 thenComparing()을 사용 studentStream.sorted(Comparator.comparing(Student::getBan) //반별로 정렬 .thenComparing(Student::getTotalScore) //총점별로 정렬 .thenComparing(Student::getName)) //이름별로 정렬 .forEach(System.out::println);
스트림의 변환
Stream<R> map(Function<? super T, ? extends R> mapper)
스트림의 요소에 저장된 값 중에서 원하는 필드만 뽑아내거나 특정 형태로 변환해야 할 때 사용되는 것이 map()이다.
예를 들어 File의 스트림에서 파일의 이름만 뽑아서 출력하고 싶을 때, 아래와 같이 map()을 사용하면 File객체에서 파일의 이름만 간단히 뽑아낼 수 있습니다.
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);
스트림의 조회
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::println);
연산과 연산 사이에 올바르게 처리되었는지 확인하고 싶다면 peek()를 사용합니다.
forEach() 최종 연산과 달리 스트림의 요소를 소모하지 않는 중간 연산입니다.
출처
자바의 정석
'Java' 카테고리의 다른 글
[Java] Optional이란? (0) 2022.02.11 [Java] 스트림의 최종연산 (0) 2022.02.10 [Java] Math.max() vs 삼항연산자 (0) 2022.02.07 [Java] Comparator와 Comparable란? (0) 2022.02.03 [Java] 스트림의 생성 (0) 2022.01.31