목차
· Stream이란?
· Stream Pipeline
· Filter
· Map
· Sorted
· Distinct
· FlatMap
Stream이란?
- 스트림은 '데이터의 흐름'이다.
- 자바 8부터 추가되어 컬렉션(Collection) 형태로 구성된 데이터를 람다를 이용해 간결하고 직관적으로 처리할 수 있게 해 준다.
- For, while 등을 이용하던 기존 loop를 대체할 수 있다.
- 쉽게 병렬 처리를 할 수 있게 해 준다.
다음 예시는 문자열 데이터를 가진 Stream을 생성하고 List로 변환했다.
Stream<String> nameStream = Stream.of("Kim", "An", "Oh");
List<String> names = nameStream.collect(Collectors.toList());
Stream Pipeline(구조)
스트림 파이프라인은 크게 세 가지로 구성되어 있다.
컬렉션으로 들어온 데이터들이 여러 개의 중간 처리 과정을 거쳐 종결처리된다.
자세한 예시는 뒤에서 확인할 수 있다.
Source (소스)
컬렉션, 배열 등
Intermediate Operations (중간 처리)
0개 이상의 filter, map 등의 중간처리
Terminal Operation (종결 처리)
Collect, reduce 등
아래에서는 중간 처리에서 사용되는 여러 스트림 함수를 확인할 수 있다.
Filter
특정 조건을 만족하는 데이터만 걸러내는 데 사용한다.
Predicate에 true를 반환하는 데이터만 존재하는 stream을 리턴한다.
Stream<T> filter(Predicate<? super T> predicate);
다음 예시는 Filter를 사용해 나이가 30 이상인 회원을 조회하는 기능이다. 2명만 필터링된 것을 확인할 수 있다.
ist<Member> members = new ArrayList<>();
members.add(new Member("Kim", 20, false));
members.add(new Member("An", 40, true));
members.add(new Member("Oh", 60, false));
List<Member> ageFilteredList = members.stream()
.filter(x -> x.getAge() > 30)
.collect(Collectors.toList());
System.out.println("ageFilteredList = " + ageFilteredList);
// ageFilteredList = [Member{name='An', age=40, isVerified=true}, Member{name='Oh', age=60, isVerified=false}]
Map
데이터를 변형하는 데 사용한다.
데이터에 해당 함수가 적용된 결과물을 제공하는 stream을 리턴한다.
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
다음 예시는 Map을 사용해 Member 리스트를 나이를 가진 Integer 리스트로 변형하는 코드이다.
List<Integer> ageList = members.stream()
.map(x -> x.getAge())
.collect(Collectors.toList());
System.out.println("ageList = " + ageList);
//ageList = [20, 40, 60]
Sorted
데이터가 순서대로 정렬된 stream을 리턴한다.
데이터의 종류에 따라 Comparator가 필요할 수 있다.
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
다음 예시는 Member 리스트를 Sorted를 사용해 이름 기준으로 알파벳 오름차순 정렬한 이후에 이름만 추출했다.
List<Member> members = new ArrayList<>();
members.add(new Member("Kim", 20, false));
members.add(new Member("An", 40, true));
members.add(new Member("Oh", 60, false));
List<String> nameAscList = members.stream()
.sorted((o1, o2) -> o1.getName().compareTo(o2.getName()))
.map(Member::getName)
.collect(Collectors.toList());
System.out.println("nameAscList = " + nameAscList);
// nameAscList = [An, Kim, Oh]
Distinct
중복되는 데이터가 제거된 stream을 리턴한다.
Stream<T> distinct();
다음 예시는 Member 리스트를 Distinct를 사용해 중복을 제거하고, 이름만 추출했다.
List<Member> members = new ArrayList<>();
members.add(new Member("Kim", 20, false));
members.add(new Member("An", 40, true));
Member oh = new Member("Oh", 60, false);
members.add(oh);
members.add(oh);
List<String> distinctList = members.stream()
.distinct()
.map(Member::getName)
.collect(Collectors.toList());
System.out.println("dis = " + distinctList);
// dis = [Kim, An, Oh]
FlatMap
Map + Flatten
데이터에 함수를 적용한 후 중첩된 stream을 연결하여 하나의 stream으로 리턴한다.
<R> Stream<R> flatMap(Function<? super T,
? extends Stream<? extends R>> mapper);
다음은 회원 리스트 정보에서 총회원이 가지고 있는 주문 리스트 정보를 가져오는 예시이다.
회원마다 주문 리스트를 가지고 있어 이 주문을 flat 하게 펼치는 작업을 flatMap을 통해 진행한다.
ArrayList<Order> firstOrders = new ArrayList<>();
firstOrders.add(new Order(BigDecimal.valueOf(10)));
firstOrders.add(new Order(BigDecimal.valueOf(20)));
ArrayList<Order> twoOrders = new ArrayList<>();
twoOrders.add(new Order(BigDecimal.valueOf(30)));
twoOrders.add(new Order(BigDecimal.valueOf(40)));
ArrayList<Order> threeOrders = new ArrayList<>();
threeOrders.add(new Order(BigDecimal.valueOf(50)));
threeOrders.add(new Order(BigDecimal.valueOf(60)));
List<Member> members = new ArrayList<>();
members.add(new Member("Kim", 20, false, firstOrders));
members.add(new Member("An", 40, true, twoOrders));
members.add(new Member("Oh", 60, false, threeOrders));
List<Order> collect = members.stream() // Stream<Member>
.map(Member::getOrders) // Stream<List<Order>>
.flatMap(List::stream) // Stream<Order>
.collect(Collectors.toList());
'Language > Java' 카테고리의 다른 글
Java 스트림 (Stream) 사용법 및 정리 3/3 (Collectors, Grouping By ..) (0) | 2022.10.10 |
---|---|
Java 스트림 (Stream) 사용법 및 정리 2/3 (Reduce, Max, Min ..) (0) | 2022.10.10 |
Java 메서드 참조란? (0) | 2022.10.09 |
Java 8 함수형 인터페이스 이해하기 (0) | 2022.10.08 |
Java 람다 표현식과 Function Interface (0) | 2022.10.08 |