기존 자바에서 배열에 있는 객체들을 가공하려면 향상된 for문과 같은 문법들을 사용했습니다.
물론 객체가 아닌 다른 자료형이어도 Stream 사용이 가능하지만 조금 더 개발에 중점을 두고자 객체에 초점을 맞추어 말하겠습니다.
하지만 만약 빌더 패턴(Builder Pattern)과 같은 것들을 사용하고, 향상된 for문으로 배열에 담겨있는 객체들을 가공하면 코드가 엄청나게 길어집니다.
그래서 자바8부터 Stream을 지원하기 시작했습니다. Stream을 사용한다면 코드가 매우 짧고 간결해집니다.
Stream에서는 배열의 원소를 가공하는 함수가 제공됩니다.
이렇게 데이터 가공을 마치고 나면 collect를 사용해서 결괏값을 리턴해줍니다.
먼저 map부터 사용해 보겠습니다.
@Override
public List<ShareMajorPostsResponseDto> all() {
return shareMajorPostsRepository.findAll().stream() // 1
.map(ShareMajorPostsResponseDto::new) // 2
.collect(Collectors.toList()); // 3
}
shareMajorPostsRepository.findAll( )은 Jpa를 사용한 컬렉션 조회입니다.
메서드 이름만 봐도 알 수 있듯이 모든 게시글을 조회하는 기능을 가지고 있습니다. 대충 저 메서드로 인해서 객체들이 배열에 담긴다고 생각하면 될 것 같습니다.
이젠 stream에 관련된 메서드를 사용할 수 있습니다.
원래 데이터의 형태는 ShareMajorPosts 입니다.
ShareMajorPostsResponseDto 클래스의 생성자는 아래와 같습니다.
@Builder
public ShareMajorPostsResponseDto(ShareMajorPosts shareMajorPosts) {
this.id = shareMajorPosts.getId();
this.title = shareMajorPosts.getTitle();
this.content = shareMajorPosts.getContent();
}
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
}
모든 게시글을 조회합니다. 처음 조회한 형태는 MajorPosts 입니다.
filter 를 사용해서 조회한 데이터에 조건을 걸어줍니다. -> 조회한 데이터의 content 가 "content" 라면
map을 통해서 MajorPosts -> ShareMajorPostsResponseDto 로 반환 해주는 모습입니다.
아까와 마찬가지로 가공된 데이터를 collect 를 사용해서 반환해 줍니다.
if 문에도 다중 조건을 걸 수 있듯이, stream 에서도 다중으로 조건을 걸 수 있습니다.
스트림에서의 다중 조건을 거는 방법은 다음과 같습니다.
@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(중복 제거) 등등 많지만 스트림을 처음 사용하는 분들이 어떻게 사용해야 할지 감이 안잡힐 것 같은 부분(내가 그랬던 부분 ㅎ;)을 위주로 알아 보았습니다.