-
Stream
- '데이터의 흐름’이다.
- 배열 또는 컬렉션 인스턴스에 함수 여러 개를 조합해서 원하는 결과를 필터링하고 가공된 결과를 얻을 수 있다.
- 람다를 이용해서 코드의 양을 줄이고 간결하게 표현할 수 있다. 즉, 배열과 컬렉션을 함수형으로 처리할 수 있다.
- 병렬처리(multi-threading)가 가능하다.
스트림 인스턴스를 생성해서 필터링, 매핑, 정렬, 그룹핑 등의 중간처리와 합계, 평균, 카운팅, 최대값, 최소값 등의 최종 처리를 파이프라인(Pipelines)으로 해결한다.
- 생성하기 : 스트림 인스턴스 생성.
- 가공하기 : 필터링(filtering) 및 맵핑(mapping) 등 원하는 결과를 만들어가는 중간 작업(intermediate operations).
- 결과 만들기 : 최종적으로 결과를 만들어내는 작업(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());
결과 : JavaDatabaseSpringCollectors.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'}
]
}'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