ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Stream
    STUDY/백엔드 2021. 4. 28. 17:58

     

    Stream

    • '데이터의 흐름’이다.
    • 배열 또는 컬렉션 인스턴스에 함수 여러 개를 조합해서 원하는 결과를 필터링하고 가공된 결과를 얻을 수 있다.
    • 람다를 이용해서 코드의 양을 줄이고 간결하게 표현할 수 있다. 즉, 배열과 컬렉션을 함수형으로 처리할 수 있다.
    • 병렬처리(multi-threading)가 가능하다.

     

    스트림 인스턴스를 생성해서 필터링, 매핑, 정렬, 그룹핑 등의 중간처리와 합계, 평균, 카운팅, 최대값, 최소값 등의 최종 처리를 파이프라인(Pipelines)으로 해결한다. 

    1. 생성하기 : 스트림 인스턴스 생성.
    2. 가공하기 : 필터링(filtering) 및 맵핑(mapping) 등 원하는 결과를 만들어가는 중간 작업(intermediate operations).
    3. 결과 만들기 : 최종적으로 결과를 만들어내는 작업(terminal operations).
    전체 -> 맵핑 -> 필터링 1 -> 필터링 2 -> ... -> 결과 만들기 -> 결과물

     

     

    Filtering

    필터(filter)은 스트림 내 요소들을 하나씩 평가해서 걸러내는 작업이다. 인자로 받는 Predicate 는 boolean 을 리턴하는 함수형 인터페이스로 평가식이 들어가게 된다.

     

    Stream<T> filter(Predicate<? super T> predicate);

     

    예제

    List<String> list = Arrays.asList("Java", "Database", "Spring");
    Stream<String> stream = list.stream()
                                          .filter(element -> element.contains("a"));

    결과 : [Java, Database]

     

    Mapping

    맵(map)은 스트림 내 요소들을 하나씩 특정 값으로 변환해준다. 이 때 값을 변환하기 위한 람다를 인자로 받는다.

     

    <R> Stream<R> map(Function<? super T, ? extends R> mapper);

     

    스트림에 들어가 있는 값이 input 이 되어서 특정 로직을 거친 후 output 이 되어 (리턴되는) 새로운 스트림에 담기게 된다. 이러한 작업을 맵핑(mapping)이라고 한다.

     

    예제1

    List<String> list = Arrays.asList("Java", "Database", "Spring");
    Stream<String> stream = list.stream()
                                          .map(String::toLowerCase);

    결과 : [java, database, spring]

     

    예제2

    public class Service {
        private int id;
        private String name;
    }

    // serviceList가 존재한다는 가정하에...
    Stream<String> stream = serviceList.stream()
                                      .map(Service::getName);

    결과 :  [Java, Database, Spring]

     

    Sorting

    정렬은 다른 정렬과 마찬가지로 Comparator 를 이용한다.

     

    Stream<T> sorted();
    Stream<T> sorted(Comparator<? super T> comparator);

     

    예제1

    List<Integer> list = Arrays.asList(18, 10, 65, 1, 7);

    List<Integer> sortedList = list.stream()
                                           .sorted()
                                           .boxed()
                                           .collect(Collectors.toList());

    결과 : [1, 7, 10, 18, 65]

     

    예제2

    List<String> list = Arrays.asList("Java", "Spring", "Database");

    list.stream()
        .sorted()
        .collect(Collectors.toList());
    // [Database, Java, Spring]

    list.stream()
        .sorted(Comparator.reverseOrder())
        .collect(Collectors.toList());

    // [Spring, Java, Database]

    list.stream()
         .sorted(Comparator.comparingInt(String::length))
         .collect(Collectors.toList());

    // [Java, Spring, Database]

     

    Peek

    peek은 스트림 내 요소들 각각을 대상으로 특정 연산을 수행하는 메소드로 스트림 내 요소들 각각에 특정 작업을 수행할 뿐 결과에 영향을 미치지 않는다. peek은 처리 대상의 상태가 변경될 수 있는 코드는 넣지 않아야 한다. 특정 결과를 반환하지 않는 함수형 인터페이스 Consumer 를 인자로 받는다.

     

    Stream<T> peek(Consumer<? super T> action);

     

    예제

    int sum = IntStream.of(1, 3, 5, 7, 9)
                              .peek(System.out::println)
                              .sum();

     

    Calculating

    스트림 API 는 다양한 종료 작업을 제공한다. 최소, 최대, 합, 평균 등 기본형 타입으로 결과를 만들어낼 수 있다.

     

    예제

    int count = IntStream.of(1, 3, 5, 7, 9).count(); 
    long sum = LongStream.of(1, 3, 5, 7, 9).sum();

    -> 스트림이 비어있는 경우 count와 sum은 0을 출력하지만, 평균, 최대, 최소의 경우에는 표현할 수 없기 때문에 Optional을 이용해 리턴한다.

    OptionalInt min = IntStream.of(1, 3, 5, 7, 9).min();
    OptionalInt max = IntStream.of(1, 3, 5, 7, 9).max();

    DoubleStream.of(1.1, 2.2, 3.3, 4.4, 5.5)
                       .average()
                       .ifPresent(System.out::println);

     

    Collectors.toList()

    스트림에서 작업한 결과를 담은 리스트로 반환한다. 

     

    예제

    List<Service> serviceList = Arrays.asList(
                                                 new Service(1, "Java"),
                                                 new Service(2, "Database"),
                                                 new Service(3, "Spring"));

    List<String> collectList = serviceList.stream()
                                                              .map(Service::getName)
                                                              .collect(Collectors.toList());

    결과 : [Java, Database, Spring]

     

    Collectors.joining()

    스트림에서 작업한 결과를 하나의 스트링으로 이어 붙일 수 있다.

     

    예제

    List<Service> serviceList = Arrays.asList(
                                                 new Service(1, "Java"),
                                                 new Service(2, "Database"),
                                                 new Service(3, "Spring"));

    List<String> collectList = serviceList.stream()
                                                   .map(Service::getName)
                                                   .collect(Collectors.joining());

    결과 : JavaDatabaseSpring

     

    Collectors.joining 은 세 개의 인자를 받을 수 있다.

    • delimiter : 각 요소 중간에 들어가 요소를 구분시켜주는 구분자
    • prefix : 결과 맨 앞에 붙는 문자
    • suffix : 결과 맨 뒤에 붙는 문자

     

    String listToString = serviceList.stream()
                                            .map(Product::getName)
                                            .collect(Collectors.joining("/", "<", ">"));

    결과 : <Java/Database/Spring>

     

    Collectors.groupingBy()

    특정 조건으로 요소들을 그룹으로 만들 수 있다. 

     

    예제

    List<Service> serviceList = Arrays.asList(
                                                 new Service(1, "Java"),
                                                 new Service(1, "Database"),
                                                 new Service(2, "Spring"));

    Map<String, List<Service>> mapOfLists = serviceList.stream()
                                                                         .collect(Collectors.groupingBy(Service::getId));

    결과 : {
              1=[
                  Service{id=1, name='Java'},
                  Service{id=1, name='Database'}
                  ],
              2=[
                  Service{id=2, name='Spring'}
                  ]
            }

     

    futurecreator.github.io/2018/08/26/java-8-streams/

    'STUDY > 백엔드' 카테고리의 다른 글

    람다 표현식  (0) 2021.05.06
    Optional  (0) 2021.05.06
    Spring Batch  (0) 2021.03.03
    메모리 영역  (0) 2021.02.08
    RestTemplate & WebClient  (0) 2021.02.03
Designed by Tistory.