Java | Stream API

바다·2024년 3월 5일
0

Java

목록 보기
7/18

Stream

  • 관리하는 데이터를 처리하기 위해 사용
  • 수집된 다양한 데이터를 활용하는데 있어서간결하고 가독성 있는 처리가 가능
  • 대부분 람다를 필요로 하기 때문에 람다를 이해하고 사용할 수 있어야 함
List<String> customersNmaes = customers.stream()
                                        .filter(customer -> customer.getAge() > 30)  //필터링
                                        .sorted() //정렬
                                        .map(Customer::getName) //매핑
                                        .collect(Collectos.toList()); //리스트형태로 반환

for(String name: customersNames) {
    System.out.println(name);
}

Stream Interface

  • long count() : 해당 스트림에 포함된 항목의 수를 반환
  • Stream concat(Stream, Stream) : 파라미터로 전달되는 두 개의 스트림을 하나의 스트림으로 반환
  • R collect(Collector) : 스트림의 항목들을 컬렉션 타입의 객체로 반환
  • Stream filter(Predicate) : 스트림의 항목들을 파라미터의 조건에 따라 필터링하고 결과 항목들을 스트림 형태로 반환
  • void forEach(Consumer) : 스트림 항목들에 대한 순회(최종 연산)
  • Optional reduce(BinaryOperator) : 람다 표현식을 기반으로 데이터를 소모하고 그 결과를 반환(최종 연산)
  • Object[] toArray() : 스트림 항목들을 배역 객체로 반환
  • Stream sorted() : 스트림 항목들에 대해 정렬하고 이를 스트림으로 반환

스트림 객체를 생성하는 방법

  1. Collection 객체를 통한 방법 -> 주로 사용
  2. 스트림 빌더를 통한 방벙
    1. 스트림 자체적으로 데이터를 생성하고 처리할 수 있다
    2. accpet(), add(), build() 메소드를 정의하고 있다

한 번 생성한 스트림은 사용 후 다시 사용할 수 없으며, 전체 데이터에 대한 처리가 이루어지면 종료된다

Stream 연산

  • 스트림을 이용한 연산은 각 연산의 연결을 통해 파이프라인을 구성할 수 있다
  • 파이프라인을 구성할 수 있다는 것은 스트림 대상 데이터에 대한 다양한 연산을 조합할 수 있다는 것을 의미
  • 스트림의 연산은 "중간 연산"과 "최종 연산"이 있다
    • 중간연산은 filter, map -> 스트림을 반환한다
    • 중간연산은 연속해서 호출하는 메소드 체이닝으로 구현 가능하다
    • 최종연산이 실행되어야 중간연산이 처리되므로 중간연산들로마 구성된 메소드는 실행되지 않는다

최종 연산

  • forEach : 스트림의 각 요소를 소비하며 람다 적용 / void 반환
  • count : 스트림 요소의 수를 반환 / Long 반환
  • collect : List, Map 형태의 컬렉션 반환
  • sum : 스트림의 모든 요소에 대한 합을 반환
  • reduce : 스트림의 요소를 하나씩 줄여가며 연산 수행 후 결과 반환 / Optional 반환

필터링

  • 필터링은 전체 데이터에서 불필요한 데이터를 없애고 원하는 데이터를 정확히 추출하기 위한 과정
  • filter(), distinct()와 같은 메소드를 이용해 데이터 추출이나 중복제거를 구현
  • distinct() : 중복 제거 연산자

정렬

  • sorted() 메소드는 특정 조건에 따라 데이터를 정렬하고 이를 다시 Stream으로 반환한다
  • sorted()를 이용한 정렬을 위해서는 반드시 대상 객체들이 Comparable 인터페이스를 구현한 클래스, 즉 비교 가능한 객체여야 한다
  • Comparable 객체가 아닐 경우나 역순 정렬, 혹은 다른 조건의 정렬에는 Comparator 인터페이스가 제공하는 여러 default, static 메소드를 이용해 정렬을 구현한다
//기존의 정렬 조건일 경우
customers.stream()
        .sorted()
        .forEach(System.out::println);

//기존의 정렬 조건이 아닌 경우
customers.stream()
        .sorted(Comparator.comparing(Customer::getName))
        .forEach(System.out::println);

매핑

  • 매핑 연산은 스트림이 관리하는 데이터를 다른 형태의 데이터로 반환할 수 있도록 한다
  • map(), mapToInt(), mapToDouble(), mapToLong()이 매핑 연산의 메소드

최종 연산

  • 스트림이 관리하는 전체 데이터에 대한 순회 작어은 최종 연산인 "forEach() 메소드"를 이용
  • "collect() 메소드"는 스트림 처리 이후 처리된 데이터에 대해 Collection 객체로 반환하는 메소드
  • 스트림의 최종 연산은 forEach()와 같은 스트림 처리 결과를 바로 확인할 수 있는 연산이 있고, 데이터를 모두 소모한 이후에 그 결과를 알 수 있는 count()와 같은 연산이 있다
profile
ᴘʜɪʟɪᴘᴘɪᴀɴs 3:14

0개의 댓글