Skip to content

Spring Data’s Page Object Converting using Collector (feat. Java8)

2016년 11월 17일

Java8 에서 stream Collection 타입을 활용해 리스트 내부 오브젝트를 바꾸는 코드를 효율적으로 작성할 수 있다.

스프링 데이터에 쓰이는 Page 오브젝트는 List Wrapper 클래스중에 하나이다. 이 클래스도 마찬가지로 stream map 함수를 사용하는 것처럼 쉽게 사용하기 위해 커스텀 Collector 클래스를 하나 작성해 보았다.

기존에 5줄 정도 사용하던 java6 용 코드를 한줄에 넣을 수 있게 되었다.

최종 활용코드는 다음과 같다.

Page<DTO> dtos = PageCollector.convert(repository.findAll(pageable), DTO:new);

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Stream.concat;

/**
 * Created by Swizzle on 2016-11-17.
 */
public class PageCollector implements Collector<T, List, Page> {

    private final Pageable pageable;
    private final long total;

    public PageCollector(Pageable pageable, long total) {
        this.pageable = pageable;
        this.total = total;
    }

    @Override
    public Supplier supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List, T> accumulator() {
        return List::add;
    }

    @Override
    public BinaryOperator combiner() {
        return (left, right) -> concat(left.stream(), right.stream()).collect(toList());
    }

    @Override
    public Function<List, Page> finisher() {
        return builder -> new PageImpl<>(builder, pageable, total);
    }

    @Override
    public Set characteristics() {
        return Collections.unmodifiableSet(Collections.EMPTY_SET);
    }

    public static  Collector<T, ?, Page> toPage(Pageable pageable, long total) {
        return new PageCollector<>(pageable, total);
    }

    public static <O, T> Page convert(Page page, Function<O, T> convertFunc) {
        return page.getContent().stream()
                .map(convertFunc)
                .collect(toPage(
                        new PageRequest(page.getNumber(), page.getSize(), page.getSort()),
                        page.getTotalElements()));
    }
}
Advertisements

From → Development

댓글 남기기

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

%d 블로거가 이것을 좋아합니다: