Java 8 (1) - 함수형 인터페이스 / 람다 표현식 / 메소드 레퍼런스

Java 8 소개
LTS 버전
- 2020기준
자바 개발자 중 약 83%가 사용
- 주요 기능
람다 표현식
메소드 레퍼런스
스트림 API
Optional<T>
- 등
LTS(Long-Term-Support) vs 비-LTS
비-LTS는 업데이트 제공 기간이 짧다
비-LTS 배포 주기는 6개월 (Java 9 부터)
비-LTS 지원 기간은 배포 이후 6개월
LTS 배포 주기는 3년 (매 6번째 배포판이 LTS가 된다)
- 실제 서비스 운영 환경(
production)에서는 LTS 버전을 권장
- 매년
3월과 9월에 새 버전 배포
Java에서 함수형 프로그래밍
함수를 1급 객체(First class Object)로 사용할 수 있다
- 순수 함수(
Pure Function)
- 부수효과(
Side Effect)가 없다 --> 함수 외부의 값을 변경하지 않는 것
- 상태가 없다 -->
함수 외부의 값을 사용하지 않는 것
- 고차 함수(
Higher-Order Function)
함수가 함수를 매개변수로 받을 수 있고, 함수를 반환할 수도 있음
- 불변성(
immutable)을 가짐
함수형 인터페이스
[ 개념 ]
추상 메소드를 딱 하나만 가지고 있는 인터페이스
- SAM(
Single Abstract Method) 인터페이스
@FuncationInterface 를 사용해서 인터페이스를 정의 (추상 메소드가 2개 이상이면 오류 발생)
[ Java에서 제공하는 함수형 인터페이스 ]
Function<T, R>
T 타입을 받아서 R 타입을 리턴하는 함수 인터페이스
모든 타입은 같을수도, 다를수도 있음
(모두 같은 경우 뒤에 나올 UnaryOperator<T>와 동일)
- 함수 조합용 메서드
- andThen :
호출한 함수의 결과에 이어서 수행
- compose :
호출된 함수를 먼저 수행 후, 호출한 함수를 수행
- 사용
R apply(T t)

BiFunction<T, U, R>
두 개의 값(T, U)를 받아서 R 타입을 리턴하는 함수 인터페이스
입력값으로 2개(T, U)를 받아서 R을 반환
모든 타입은 같을수도, 다를수도 있음
(모두 같은 경우 뒤에 나올 BinaryOperator<T>와 동일)
- 사용
Consumer< T >
T 타입을 받아서 아무 값도 리턴하지 않는 함수 인터페이스
반환을 하지 않음 --> 보통 내부에서 출력을 처리하는 경우에 사용
- 사용
Supplier< T >
매개변수를 받지 않고, T 타입을 반환하는 함수 인터페이스
받아올 입력값의 타입을 T 로 지정
- 사용
Predicate< T >
T 타입을 받아서 boolean을 리턴하는 함수 인터페이스
T 타입을 받아서 True / False를 반환
- 조합용 메소드
- 사용
UnaryOperator< T >
Function<T,R> 중 T와 R의 타입이 같은 경우를 의미하는 함수 인터페이스
BinaryOperator< T >
BiFunction<T,U,R> 중 T, U, R 모두 같은 타입인 경우를 의미하는 함수 인터페이스
Bi가 붙으면 2개의 입력을 받는다고 이해하면 된다
람다 표현식(Lambda Expressions)
[ 설명 ]
함수형 인터페이스의 인스턴스를 만드는 방법으로 쓰일 수 있음
코드를 줄일 수 있음
- 메소드
매개변수, 리턴 타입, 변수로 만들어 사용
- 사용
- 인자 리스트
- 인자가 없을 때 :
()
- 인자가 한 개 일때 :
(one) 또는 one
- 인자가 여러개 일 때 :
(one, two)
- 인자의 타입은 생략 가능,
컴파일러가 추론(infer)하기 때문!
(명시를 할 수도 있음)
- 바디
여러 줄인 경우에는 중괄호인 {}를 사용해서 묶는다
한 줄인 경우에 는 중괄호와 return을 생략 가능
- 변수 캡처(
Variable Capture)
- 로컬 변수 캡처
final 혹은 effective final 인 경우에만 참조 가능
--> 그 외인 경우에는 concurrency 문제로 인해 컴파일 오류를 발생 시킴
- effective final
사실상 final인 변수를 의미
이후에 변경되지 않으면 사실상 final을 선언한 것과 다를게 없음
람다는 새로운 Scope를 형성하지 않아서, 쉐도잉(Shadowing)이 일어나지 X
(로컬 클래스 / 익명 클래스는 새로운 Scope를 형성해서 클래스 내부에 같은 이름의 변수를 만들고 사용 가능!)
메소드 레퍼런스
람다가 하는 일이 기존 메소드 또는 생성자를 호출하는 것이었다
--> 메소드 레퍼런스를 사용하면 매우 간결하게 표현할 수 있다
(콜론 2개 :: 를 사용)
- 메소드 참조 방법
- Static 메소드 참조
- 특정 객체의 인스턴스 메소드 참조
- 임의 객체의 인스턴스 메소드 참조
- 생성자 참조
