Filtering
필터(filter)은 스트림 내 요소들을 하나씩 평가해서 걸러내는 작업을 수행.
인자로 받는 Predicate 는 boolean 을 리턴하는 함수형 인터페이스로 평가식이 들어가게 된다.
Stream<T> filter(Predicate<? super T> predicate);
사용법
collection.stream().filter(name -> name.contains("a"));
Mapping
맵(map)은 스트림 내 요소들을 하나씩 특정 값으로 변환해준다. 이 때 값을 변환하기 위한 람다를 인자로 받는다.
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
사용법
//대문자로 변환하여 스트림이 만들어짐
collection.stream().map(String::toUpperCase);
//객체의 getAmount 값으로 스트림이 만들어짐
productList.stream().map(Product::getAmount);
flatMap
인자로 mapper를 받고 있는데, 리턴 타입이 Stream 이다. 즉, 새로운 스트림을 생성해서 리턴하는 람다를 넘겨야한다.
flatMap 은 중첩 구조를 한 단계 제거하고 단일 컬렉션으로 만들어주는 역할을 한다.
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
List<String> flatList =
list.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
students.stream()
.flatMapToInt(student ->
IntStream.of(student.getKor(),
student.getEng(),
student.getMath()))
.average().ifPresent(avg ->
System.out.println(Math.round(avg * 10)/10.0));
Sorted
정렬 처리를 한다. 인자 없이 그냥 호출할 경우 오름차순 정렬이 된다.
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
Reduce
reduce를 통해 스트림 원소들의 결과값을 도출할 수 있다.
- accumulator : 각 요소를 처리하는 계산 로직. 각 요소가 올 때마다 중간 결과를 생성하는 로직.
- identity : 계산을 위한 초기값으로 스트림이 비어서 계산할 내용이 없더라도 이 값은 리턴.
- combiner : 병렬(parallel) 스트림에서 나눠 계산한 결과를 하나로 합치는 동작하는 로직.
// 1개 (accumulator)
Optional<T> reduce(BinaryOperator<T> accumulator);
// 2개 (identity)
T reduce(T identity, BinaryOperator<T> accumulator);
// 3개 (combiner)
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
Collecting
컬렉터는 스트림의 종료 작업 중 하나이다. Collector 타입의 인자를 받아서 처리 하는데, 자주 사용하는 작업은 Collectors 객체에서 제공해준다.
Collectors.toList()
스트림에서 작업한 결과를 담은 리스트로 반환.
List<String> collectedList =
productList.stream()
.map(Product::getName)
.collect(Collectors.toList());
Collectors.joining()
스트림에서 작업한 결과를 하나의 스트링으로 이어 붙일 수 있다.
String listToString =
productList.stream()
.map(Product::getName)
.collect(Collectors.joining())
Collectors.joining 은 3개의 파라미터를 받는다.
- delimiter : 각 요소 중간에 들어가 요소를 구분시켜주는 구분자
- prefix : 결과 맨 앞에 붙는 문자
- suffix : 결과 맨 뒤에 붙는 문자
Collectors.groupingBy()
특정 조건으로 요소들을 그룹 짓는다.
Map<Integer, List<Product>> collectorMapOfLists =
productList.stream()
.collect(Collectors.groupingBy(Product::getAmount));
Product 객체의 getAmount 를 기준으로 그루핑되어 amount값을 키값으로 가지게 되고, 해당 키값을 가진 원소들이 리스트에 그루핑되어 들어간다.
Collectors.partitioningBy()
groupingBy는 함수형 인터페이스 Function 을 이용해서 특정 값을 기준으로 스트림 내 요소들을 묶었다면, partitioningBy는 함수형 인터페이스 Predicate 를 받고, boolean 값에 따라 두가지로 분리된다.(true, false)
Map<Boolean, List<Product>> partitionedMap =
productList.stream()
.collect(Collectors.partitioningBy(el -> el.getAmount() > 15));
Collectors.collectingAndThen()
특정 타입으로 결과를 collect 한 이후에 추가 작업이 필요한 경우에 사용할 수 있다. 이 메소드의 시그니쳐는 finisher 가 추가된 모양인데, 이 피니셔는 collect 를 한 후에 실행할 작업을 의미한다.
public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(
Collector<T,A,R> downstream,
Function<R,RR> finisher) { ... }
Collectors.toSet() 한 후 수정 불가한 Set 으로 추가적으로 변환하는 코드
Set<Product> unmodifiableSet =
productList.stream()
.collect(Collectors.collectingAndThen(Collectors.toSet(),
Collections::unmodifiableSet));
Matching
매칭은 조건식 람다 Predicate 를 받아서 해당 조건을 만족하는 요소가 있는지 체크한 결과를 리턴한다. 세 가지 메소드가 존재함.
- 하나라도 조건을 만족하는 요소가 있는지(anyMatch)
- 모두 조건을 만족하는지(allMatch)
- 모두 조건을 만족하지 않는지(noneMatch)
List<String> names = Arrays.asList("Eric", "Elena", "Java");
boolean anyMatch = names.stream()
.anyMatch(name -> name.contains("a"));
boolean allMatch = names.stream()
.allMatch(name -> name.length() > 3);
boolean noneMatch = names.stream()
.noneMatch(name -> name.endsWith("s"));
Foreach
foreach 는 요소를 돌면서 실행되는 최종 작업. peek 과는 중간 작업과 최종 작업의 차이가 있다.
names.stream().forEach(System.out::println);
'JAVA' 카테고리의 다른 글
JPA @ManyToMany (0) | 2021.04.23 |
---|---|
JPA @Inheritance (0) | 2021.04.23 |
JPA CASCADE 종류 (0) | 2021.04.22 |
JAVA Optional 기초 (0) | 2021.03.19 |
자바에서 제공하는 함수형 인터페이스 (0) | 2021.03.18 |