자바8 - Stream

현시기얌·2021년 8월 14일
0

JAVA8

목록 보기
5/8

Stream

  • sequence of elements supporting sequential and parallel aggregate operations
    = 연속된 데이터를 처리하는 오퍼레이션들의 모음
  • 데이터를 담고 있는 저장소 (컬렉션)가 아니다.
  • Functional in nature, 스트림이 처리하는 데이터 소스를 변경하지 않는다.
    List<String> names = new ArrayList<>();

        names.add("hyunsik");
        names.add("aaa");
        names.add("bbb");
        names.add("ccc");

        Stream<String> stringStream = names.stream().map(String::toUpperCase);
        
        // stringStream은 그저 List에 있는 name들을 대문자한 스트림일 뿐이다.
        // stringStream이 생성되었다고 해서 List안에 있는 names들이 대문자로 바뀌는 것이 아니다. 
 
        
  • 스트림으로 처리하는 데이터는 오직 한번만 처리한다.

  • 무제한일 수도 있다. (Short Circuit 메소드를 사용해서 제한할 수 있다.) ex) 처음 10개 데이터만 받을래!!

  • 스트림 오퍼레이션은 크게 중개 오퍼레이션과 종료 오퍼레이션으로 나눌 수 있다.

Stream PipeLine

  • 0 또는 다수의 중개 오퍼레이션(Intermeditate Opertaion)과 한개의 종료 오퍼레이션(Terminal Operation)으로 구성한다.
  • 스트림의 데이터 소스는 오직 터미널 오퍼네이션을 실행할 때에만 처리한다.

Intermediate Operation (중개 오퍼레이션)

  • Stream을 리턴한다.

  • Stateless / Stateful 오퍼레이션으로 더 상세하게 구분할 수도 있다.

    • 대부분은 Stateless지만 distinct나 sorted처럼 이전 소스 데이터를 참조해야 하는 오퍼레이션은 Stateful 오퍼레이션이다.)
  • filter, map, limit, skip, sorted ...

Terminal Operation (종료 오퍼레이션)

  • Stream을 리턴하지 않는다.
  • collect, allMatch, count, forEach, min, max ...

Intermidiate Operation VS Teminal Operation

중개 오퍼레이션종료 오퍼레이션
리턴 타입StreamStream이 아닌 다른 타입 Ex) List, Collection...
  • 중개 오퍼레이션은 근본적으로 lazy 하다.

    -> 종료 오퍼레이션이 있어야지만 중개 오퍼레이션이 실행된다. (때문에 종료 오퍼레이션은 반드시 한개 필요하다.)
    -> 만약 종료 오퍼레이션이 없다면 중개 오퍼레이션들은 정의만 될 뿐 실행되지는 않는다.
  Stream<String> mapStream = names.stream()
                .map(s -> {
                    System.out.println(s);
                    return s.toUpperCase();
                });

결과 :
(System.out.println이 출력되지 않음)

         System.out.println("=====================");

        List<String> toUpperNameList = names.stream()
                .map(s -> {
                    System.out.println("중개 오퍼레이션 실행!!");
                    return s.toUpperCase();
                })
                .collect(Collectors.toList());
        toUpperNameList.forEach(System.out::println);

        System.out.println("=====================");
        System.out.println("names List는 그대로 입니다!!");
        names.forEach(System.out::println);
        System.out.println("=====================");

결과 :
(종료 오퍼레이션이 있어야 중개 오퍼레이션이 실행된다.)

  • 손쉽게 병렬 처리할 수 있다.
 for (String name : names) {
            if (name.startsWith("h")) {
                System.out.println(name.toUpperCase());
            }
        }

위와 같이 iterator를 사용하면 병렬적으로 처리하기 힘들다.

   List<String> collect = names.parallelStream().filter(n -> n.startsWith("h")).map(s -> {
            System.out.println(s + " " + Thread.currentThread().getName());
            return s.toUpperCase();
        }).collect(Collectors.toList());
        collect.forEach(System.out::println);

parallelStream()를 사용하여 병렬적으로 처리할 수 있다.
cf) 병렬적 처리가 무조건 빠르건 아니다.
결과 :

profile
현시깁니다

0개의 댓글

관련 채용 정보