스트림(Stream) 이란 ? - 배열

0

JPA

목록 보기
15/16

스트림이란 ?

기존 자바에서 배열에 있는 객체들을 가공하려면 향상된 for문과 같은 문법들을 사용했습니다.

물론 객체가 아닌 다른 자료형이어도 Stream 사용이 가능하지만 조금 더 개발에 중점을 두고자 객체에 초점을 맞추어 말하겠습니다.

하지만 만약 빌더 패턴(Builder Pattern)과 같은 것들을 사용하고, 향상된 for문으로 배열에 담겨있는 객체들을 가공하면 코드가 엄청나게 길어집니다.

그래서 자바8부터 Stream을 지원하기 시작했습니다. Stream을 사용한다면 코드가 매우 짧고 간결해집니다.

Stream에서는 배열의 원소를 가공하는 함수가 제공됩니다.

  • map : 요소들을 특정 조건에 해당하는 값으로 변환해줍니다.
  • filter : 요소들을 조건에 따라 처리합니다.

이렇게 데이터 가공을 마치고 나면 collect를 사용해서 결괏값을 리턴해줍니다.


map

먼저 map부터 사용해 보겠습니다.

@Override
    public List<ShareMajorPostsResponseDto> all() {
        return shareMajorPostsRepository.findAll().stream() // 1
                .map(ShareMajorPostsResponseDto::new) // 2
                .collect(Collectors.toList()); // 3
    }

shareMajorPostsRepository.findAll( )은 Jpa를 사용한 컬렉션 조회입니다.
메서드 이름만 봐도 알 수 있듯이 모든 게시글을 조회하는 기능을 가지고 있습니다. 대충 저 메서드로 인해서 객체들이 배열에 담긴다고 생각하면 될 것 같습니다.

  1. findAll로 객체들을 배열에 담고 .stream을 호출합니다.

이젠 stream에 관련된 메서드를 사용할 수 있습니다.
원래 데이터의 형태는 ShareMajorPosts 입니다.

  1. map으로 받아온 데이터(ShareMajorPosts)들을 ShareMajorPostsResponseDto의 형태로 변환해줍니다.

ShareMajorPostsResponseDto 클래스의 생성자는 아래와 같습니다.

@Builder
    public ShareMajorPostsResponseDto(ShareMajorPosts shareMajorPosts) {
        this.id = shareMajorPosts.getId();
        this.title = shareMajorPosts.getTitle();
        this.content = shareMajorPosts.getContent();
    }
  1. 데이터 가공의 모든 과정이 끝났기 때문에 collect를 사용해서 결괏값을 반환해 줍니다.

filter

filter는 컬렉션계의 if 라고 생각하시면 됩니다. 솔직히 jpa를 사용할 때는 @Query 를 사용해서 where 문을 작성해주면 되긴 하지만 일단 스트림을 배우기로 했으니 한 번 사용해 보겠습니다.

백문이 불여일견이라는 말이 괜히 있는 것이 아니니 바로 코드를 보면서 이해해 봅시다.

@Override
    public List<ShareMajorPostsResponseDto> all() {
        return shareMajorPostsRepository.findAll().stream() // 1
                .filter(shareMajorPosts -> 
                	shareMajorPosts.getContent().equals("content")) // 2
                .map(ShareMajorPostsResponseDto::new) // 3
                .collect(Collectors.toList()); // 4
    }
  1. 모든 게시글을 조회합니다. 처음 조회한 형태는 MajorPosts 입니다.

  2. filter 를 사용해서 조회한 데이터에 조건을 걸어줍니다. -> 조회한 데이터의 content 가 "content" 라면

  3. map을 통해서 MajorPosts -> ShareMajorPostsResponseDto 로 반환 해주는 모습입니다.

  4. 아까와 마찬가지로 가공된 데이터를 collect 를 사용해서 반환해 줍니다.

다중 filter 사용하기

if 문에도 다중 조건을 걸 수 있듯이, stream 에서도 다중으로 조건을 걸 수 있습니다.
스트림에서의 다중 조건을 거는 방법은 다음과 같습니다.

filter 2개 사용하기

    @Override
    public List<ShareMajorPostsResponseDto> all() {
        return shareMajorPostsRepository.findAll().stream()
                .filter(shareMajorPosts -> shareMajorPosts.getTitle().equals("title"))
                .filter(shareMajorPosts -> shareMajorPosts.getContent().equals("content"))
                .map(ShareMajorPostsResponseDto::new)
                .collect(Collectors.toList());
    }

&& 연산자 사용하기

    @Override
    public List<ShareMajorPostsResponseDto> all() {
        return shareMajorPostsRepository.findAll().stream()
                .filter(shareMajorPosts -> shareMajorPosts.getTitle().equals("title") 
                        && shareMajorPosts.getContent().equals("content"))
                .map(ShareMajorPostsResponseDto::new)
                .collect(Collectors.toList());
    }

스트림에서 제공하는 기능은 sorted(정렬), distinct(중복 제거) 등등 많지만 스트림을 처음 사용하는 분들이 어떻게 사용해야 할지 감이 안잡힐 것 같은 부분(내가 그랬던 부분 ㅎ;)을 위주로 알아 보았습니다.

0개의 댓글