ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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

    댓글

Designed by Tistory.