-
Java Stream(Lambda) 주요 메소드Java 2022. 2. 7. 00:16
회사에서 fastcampus 강의 수강을 지원해줘서 Java Stream에 관한 강의를 수강했다. stream은 지금도 자주 쓰고는 있지만 좀 더 잘 활용할 수 있는 방법을 터득하고 싶었다. 이 강의를 통해 어떤 stream에 관련된 메소드들이 있는지 알 수 있었다. 실무에서도 자주 쓸 수 있을 것 같다.
Functional Programming
- How to do에 초점을 맞추는 명령형 프로그래밍과는 달리 선언형 프로그래밍(Functional Programming)에서는 what to do에 초점을 맞춘다.
- 1급 시민으로서의 함수란? 함수가 parameter, return object 등 변수처럼 사용되는 것.
- Functional Programming의 장점 : 높은 가독성과 확장성, 원활한 유지보수
Functional Interface
- Consumer
- Function
- Operator
- Predicate
- Supplier
Stream
- Stream을 왜 써야 할까? -> 가독성, 반복 코드 삭제, 병렬처리 등
- Stream은 왜 일회용일까? -> Stream을 통해 네트워크, 파일 입출력도 처리하려다 보니 자원이 일회용일 경우도 커버해야 했기 때문
- Stream의 구성 요소 (종결 처리의 실행이 필요할때, 중간 처리들도 비로소 실행됨)
- Source (자원)
- Intermediate Operations (중간 처리)
- Terminal Operations (종결 처리)
- filter, map, sorted, distinct, flatMap
- max, min, count
- allMatch, anyMatch
- findFirst, findAny
- findAny는 순서가 중요하지 않을 때 사용. (parallel stream과 같이 사용할 때 최적화)
- reduce
- 주어진 함수를 반복 적용하여 stream 내 데이터를 하나의 값으로 합침
- max, min, count도 reduce의 일종
- First reduce -> 주어진 accumulator를 이용해 데이터를 합침.
- Second reduce -> 주어진 accumulator를 이용해 데이터를 합침. reduce가 실행되지 않을 경우 identity 반환
- Third reduce -> 합치는 과정에서 타입이 바뀌게 되는 경우 사용됨. (map + reduce로 대체 가능)
- collect
- Collectors.toList
- Collectors.toSet
- Collectors.toMap (stream 내 데이터를 그대로 key 또는 value로 사용할 경우, Function.identity()를 사용할 수 있음)
- Collectors.mapping
- Collectors.reducing
- Collectors.groupingBy
- Collectors.positioningBy
- forEach
- 매개변수로 입력된 람다식을 stream의 각 데이터에 적용해주는 종결 처리 메소드
- iterable interface에도 forEach가 선언되어 있기 때문에 stream의 중간 처리가 필요 없다면 Set, List 등 iterable collection에서 바로 사용할 수도 있음
- 반복문 내에서 index를 사용해야 하는 경우 IntStream.range 사용
- parallel stream
- 여러개의 스레드를 이용하여 stream의 처리 과정을 병렬화
- 중간 과정은 병렬처리됨
- 종결 처리 과정에서 Collectors.toList를 사용한다면 결과물이 기존의 sequence에 맞춰서 순차적으로 생성됨(중간 과정은 여전히 병렬처리)
- 장점
- 간단하게 병렬처리 가능
- 비약적인 속도 향상
- 단점
- 향상 속도가 빨라지는 것은 아님
- 공통으로 사용하는 리소스가 있으면 잘못된 결과가 생성되거나 deadlock 오류 발생 가능
- 위 단점을 막기 위해 mutext, semaphore 등 병렬 처리 기술을 이용할 수 있긴 한데, 오히려 순차처리보다 느려질 가능성 존재
Optional
- NPE를 쉽게 해결하기 위해 등장
- of / ofNullable / empty
- get / orElse / orElseGet / orElseThrow
- isPresent / ifPresent
- map / flatMap
Advanced Functional Programming
- lexical scope
- 함수 내부에 함수가 있을 때, 내부 함수에서 외부 함수에 있는 변수 사용 가능(반대는 불가능)
- closure
- 내부 함수가 존재하는 한, 내부 함수가 사용한 외부 함수의 변수들 역시 계속 존재. 이러한 lexical scope를 포함하는 함수를 closure라고 함
- 내부 함수가 사용한 외부 함수의 변수들은 내부 함수 선언 당시로부터 변경될 수 없기 때문에 final로 선언되지 않더라도 암묵적으로 final이 적용된다.
- curry
- closure를 응용한 기술로써, 여러 개의 매개변수를 받는 함수를 중첩된 여러 개의 함수로 쪼개는 방법. 매개 변수를 한 번에 받지 않고 여러 단계에 걸쳐 나눠 받을 수 있게 함.
- lazy evaluation
- lambda는 그 결과값이 필요할 때에만 실행. 불필요한 실행을 줄이고 해당 코드의 실행 순서를 의도적으로 미룰 수 있음.
- function composition
- n개의 함수를 합쳐서 새로운 하나의 함수를 만드는 것
Design Pattern
- builder pattern
- decorator pattern
- strategy pattern
- template method pattern
- chain of responsibility pattern
'Java' 카테고리의 다른 글
stackoverflow 번역하기 :: @PostConstruct를 왜 사용할까? (0) 2021.07.25 댓글