Stream API 활용편1 (필터와 슬라이싱)
안녕하세요. 블로그 주인인 초보프로그래머입니당.
오랜만의 블로그 포스팅입니다. 개인적으로 바쁜 일이 있어서(곧 회사내에서 출시를 하기 때문에 버그를 열심히 잡았죠... ㅡㅡ^), 오랜만에 공부를 해보고 내용을 정리하게 되었습니다.
솔직히 블로그할 시간은 있긴 했지만, 게을러지다보니 공부하게 되는 것이 쉽지가 않네요.
하지만 책을 산 것이 아깝고, 곧 진행했던 안드로이드 프로젝트에도 함수형 프로그래밍의 결실을 시도해봐야하니(RxJava or Android N) 다시 한번 붙잡게 되었습니다.
그런 의미에서 오늘은 계속 진행하던 Stream API 의 활용에 대해 보고자 합니다.
Stream API에 대해 처음보게 된다면 이 곳을 먼저 확인해주세요.
이전에 Stream API를 소개할 때, 컨테이너(Collection)의 활용을 질의 형태로 작성할 수 있다고 언급했었는데요. 마치 고수준 언어인 SQL을 사용하듯 말이죠. (Collection 객체를 테이블이라고 본다면, 질의를 통해 어떤 결과를 얻는다 생각하면 좋겠네요? ㅡㅡ^)
오늘은 그 중 필터링과 슬라이싱(즉 검색.. ㅡㅡ^)을 해보려 합니다.
1. 필터링
SQL의 where 절과 같은 역할입니다. Collection 객체 중 프리디케이트(Predicate)에 부합하는 객체들을 따로 추출하는 역할을 합니다. 그 메소드는 이전부터 많은 예제로 사용되었던 filter 입니다.
몸풀기로 시작해보겠습니다.
1 2 3 4 5 6 7 8 9 | List<Integer> numberList = Arrays.asList(2, 2, 3, 4, 5, 6, 8, 8, 9, 10); for (Integer a : numberList.stream().filter(a -> a % 2 == 0). collect(Collectors.toList())) { System.out.println(a); } console result : [2,2,4,6,8,8,10] | cs |
filter 메소드를 이용하여, 짝수만을 조회하였습니다. SQL로 치자면, 이정도??
1 | SELECT number FROM NUMBERLIST WHERE number % 2 = 0; | cs |
2. 고유 요소 필터링
위의 결과 중, 중복된 결과가 있습니다. 원하는 결과가 중복된 값이 없기를 바란다면 distinct 메소드를 사용해주면 됩니다.
1 2 3 4 5 | for (Integer a : numberList.stream().filter(a -> a % 2 == 0). distinct().collect(Collectors.toList())) { System.out.println(a); } | cs |
생각해보면 SQL에서 DISTINCT 를 사용하여, 고유 결과를 출력할 수 있다는 것을 알고 있습니다.
1 | SELECT DISTINCT number FROM NUMBERLIST WHERE number % 2 = 0; | cs |
3. 결과값 제한과 스킵
보통 게시판을 만들 때, limit offset 등을 사용하여 페이징 처리를 하곤 합니다. 왜냐하면 많은 데이터를 한번에 다 보여줄 수도 없거니와, 사용도 불편하기 때문이죠.
Stream API에서는 limit offset 과 같은 역할을 해줄 수 있는 메소드 역시 가지고 있습니다.
일단 Stream을 잘 살펴보면, limit 라는 메소드를 가지고 있습니다. 아래 코드는 Stream의 결과 중, 3개를 반환하는 메소드입니다.
1 2 3 | numberList.stream().filter(a -> a % 2 == 0).distinct().limit(3).forEach(System.out::println); console result : [2,4,6] | cs |
재미있는 점은 limit를 사용하지 않은 결과보다, limit의 파라미터 값이 크더라도 에러를 출력하지 않습니다. 이 점은 우리가 최대 몇개를 가져온다라는 비지니스 로직을 구현할 때, 방어코드를 할 필요가 없어졌음을 말합니다.
마지막으로 skip을 이용하여, 요소를 건너뛸 수 있습니다. 예를들어 3번째 결과부터 2개 출력이라 하면 이렇게 응용을 할 수 있습니다.
1 2 3 | numberList.stream().filter(a -> a % 2 == 0).distinct().skip(3).limit(2).forEach(System.out::println); console result : [8,10] | cs |
skip역시 입력받는 파라미터에 대해 방어코드를 할 필요가 없습니다. 조건에 만족하지 못한다면 빈 배열을 출력합니다.
오늘 포스팅에서는 Stream API를 이용한 필터 및 슬라이싱하는 방법을 알아봤습니다.
어느정도 함수형 프로그래밍의 감이 오시나요?
오늘 포스팅으로 부터 알 수 있는 점은 함수형 프로그래밍으로 비지니스 로직을 구현 시,
1. 간편하고, 직관적인 선언형 위주의 구현
2. 방어코드 없이, 오류가 적은 코드의 구현
이라는 장점을 볼 수 있었음을 알 수 있었습니다.
|
'개발이야기 > 함수형 프로그래밍' 카테고리의 다른 글
Stream API 활용편3 (검색과 매칭) (0) | 2017.01.18 |
---|---|
Stream API 활용편2 (매핑) (0) | 2016.08.27 |
Stream과 Collection 차이 (0) | 2016.08.04 |
Stream API (0) | 2016.08.03 |
람다 조합 (0) | 2016.08.02 |