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() : 스트림 항목들에 대해 정렬하고 이를 스트림으로 반환
스트림 객체를 생성하는 방법
- Collection 객체를 통한 방법 -> 주로 사용
- 스트림 빌더를 통한 방벙
- 스트림 자체적으로 데이터를 생성하고 처리할 수 있다
- 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()와 같은 연산이 있다