ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스트림의 연산 - 중간 연산
    JAVA/스트림 2023. 8. 8. 22:47

    1. 스트림 자르기 - skip(), limit()

     

    Stream<T> skip(long n)          // 앞에서부터 n개 건너뛰기
    Stream<T> limit(long maxSize)   // maxSize 이후의 요소는 잘라냄

    IntStream intStream = IntStream.rangeClosed(1, 10);    // 12345678910
    intStream.skip(3).limit(5).forEach(System.out::print); // 45678만 출력

     

     

     

     

    2. 스트림 요소 걸러내기 - filter(), distinct()

     

    Stream<T> filter(Predicate<? super T> predicate // 조건에 맞지 않는 요소 제거

    Stream<T> distinct()          // 중복 제거

     

    distinct() 예시 코드

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

     

    filter() 예시 코드

    IntStream intStream = IntStream.rangeClosed(1, 10);      // 1 2 3 4 5 6 7 8 9 10
    intStream.filter(i->i%2==0).forEach(System.out::print);  // 2 4 6 8 10만 출력

     

    intStream.filter(i->i%2==0 && i%3!=0).forEach(System.out::print);
    intStream.filter(i->i%2==0).filter(i->i%3!=0).forEach(System.out::print);

    filter()는 중간 연산자이니 여러번 사용 가능하다. &&를 통해 두 번 사용해도 되고 filter()를 두 번 붙여줘도 된다.

     

     

     

     

     

    3. 스트림 정렬하기 - sorted()

    Stream<T> sorted()                                                                 // 스트림 요소의 기본 정렬(Comparable)로 정렬

    Stream<T> sorted(Comparator<? super T> comparator)       // 지정된 Comparator로 정렬

     

    strStream.sorted(Comparator.reverseOrder())                       // 기본 정렬의 역순으로 정렬

     

     

    Comparator의 comparing() 정렬

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

    studentStream에서 Student 객체 하나씩을 Name으로 정렬하는 것이다.

     

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

    thenComparing을 통해서 정렬 기준을 여러개로 정할 수도 있다. 이름 순으로 정렬하고, 성적순으로 정렬하는 것이다.

     

     

     

     

     

    4.  스트림의 요소 변환하기 - map()

    Stream<R> map(Function<? super T, ? extend R> mapper

    Stream<File> fileStream = Stream.of(new File("one.java"), new File("two"),
                   new File("three.java"), new File("four.txt"));
                   
    Stream<String> filenameStream = fileStream.map(File::getName);
    filenameStream.forEach(System.out::println); // 스트림의 모든 파일의 이름을 출력

    fileStream이라는 스트림에서 파일들을 받아온 다음 fileStream.map()을 통해 file의 이름들을 map을 변환해서 그 요소들을 filenameStream이라는 String 타입의 스트림으로받아온 것이다.

     

     

    파일 스트림에서 파일 확장자를 중복없이 뽑아내는 예제

    fileStream.map(File::getName)
        .filter(s -> s.indexOf('.') != -1)        // 확장자가 없는 것은 제외
        .map(s -> s.substring(s.indexOf('.')+1))  // 확장자만 뽑아낸 것 (one.java면 java만)
        .map(String::toUpperCase)                 // 대문자로 변환
        .distinct()
        .forEach(System.out::print);  // JAVAJAVATXT 출력

    map이 총 3번 쓰였는데 맨 위는 Stream<File> -> Stream<String>으로 변환한 것이고 나머지 둘은 타입의 변환은 이루어지지 않는 것이다.

     

     

     

     

    5. 스트림의 요소를 소비하지 않고 조회하기 - peak()

    스트림을 소비하는 최종 연산인 forEach()와 달리 peak()는 중간 연산이며 스트림을 소비하지 않는다.

    Stream<T> peek(Consumer<? super T> action)

    fileStream.map(File::getName)
        .filter(s -> s.indexOf('.') != -1)        // 확장자가 없는 것은 제외
        .peak(s -> System.out.printf("filename = %s%n", s)) // 파일명 출력
        .map(s -> s.substring(s.indexOf('.')+1))  // 확장자만 뽑아낸 것 (one.java면 java만)
        .peak(s -> System.out.printf("extension = %s%n", s)) // 확장자를 출력
        .forEach(System.out::print);  // JAVAJAVATXT 출력

    위의 예제에서 peak()을 추가했는데 중간 중간 결과를 보기 위해서 사용된다.

     

     

     

     

    6. 스트림의 스트림을 스트림으로 변환 - flatMap()

    Stream<String[]> strArrStrm = Stream.of(new String[]{"abc", "def", "ghi"  },
                                            new String[]{"ABC", "DEF", "JKLMN"});
                  // 스트림 요소 하나 하나가 배열로 되어있음
                  
    Stream<Stream<String>> strStrStrm = strArrStrm.map(Arrays::stream);

    위와 같은 상황은 스트림의 스트림이 된다.

    | "aaa", "bbb" |      | "abc", "ABC" |      | "ccc", "ddd" |

    위의 3개가 모두 스트림이고 3개의 모임이 스트림으로 되어있기 때문이다.

    배열이 있을 때 map을 사용하면 이렇게 된다.

     

     

    이거를 하나의 스트림 -> "abc", "bbb", "abc", "ABC", "ccc", "ddd"로 바꾸기 위해 사용되는 것이 flatMap()이다.

    Stream<String> strstrStrms = strArrStrm.flatMap(Arrays::stream);

     map이 아니라 flatMap을 사용하면 하나의 스트림이 된다.

    'JAVA > 스트림' 카테고리의 다른 글

    collect()와 Collectors  (0) 2023.08.09
    Optinal  (0) 2023.08.09
    스트림의 연산 - 최종 연산  (0) 2023.08.08
    스트림 만들기  (0) 2023.08.08
    스트림  (0) 2023.08.08
Designed by Tistory.