들어가기
자바의 람다는 자바언어에서 쉽고 간편하게 함수를 선언해서 사용하기위한 수단이다.
하지만 자바는 객체 지향언어이고 기본적인 프로그래밍의 단위는 Class이다.
자바에서 구현하는 함수는 이 class의 범위를 벗어 날수가 없다.
함수적 인터페이스(추상클래스가 하나뿐인 인터페이스)를 구현하여 함수를 생성하고 사용하는 매커니즘을 통해서 함수형 프로그래밍을 지원하며, 람다식은 이것에 특화된 문법일 뿐이다.
실질적으로 함수 한개를 생성해서 사용하는 것 뿐이지만, 결과적으로는 함수적 인터페이스를 즉흥적으로 구현한 익명객체의 메소드를 사용하게 되는 것이다.
여기서 고민해볼게 생긴다.
재사용이 필요없고, 즉흥적으로 함수를 구현하기 위해서 익명객체를 생성하는것 까지는 넘어간다 하더라도, 일일이 구현해야 할 함수적 인터페이스를 만들어 줘야 하나?
1 |
|
만약 위 처럼 인자만 다르고 하는 일은 똑같은 함수를 구현하기위해 인터페이스를 두개나 만들어야 하는 것인가?
위와 같은 고민은 전혀 할 필요가 없다.
정답은 java.util.function 표준 API 패키지에 있다.
Java8에서는 기능적으로 분류된 자주 사용햘 만한 함수형 인터페이스를 API로 제공하고 있기때문에, 그냥 해당 API의 인터페이스를 입맛에 맞게 구현해서 사용하면 된다.
기본으로 제공되는 함수적 인터페이스의 종류
종류 | 추상 메소드 특징 | 비고 |
---|---|---|
Consumer | 매개값은 있고, 리턴값은 없음 | |
Supplier | 매개값은 없고, 리턴값은 있음 | |
Function | 매개값도 있고, 리턴값도 있음 | 주로 매개값을 연산하고 결과를 리턴 |
Operator | 매개값도 있고, 리턴값도 있음 | 주로 매개값을 연산하고 결과를 리턴 |
Predicate | 매개값은 있고, 리턴 값은 boolean | 매개값을 조사하고 true/false를 리턴 |
java.util.function에서 제공하는 인터페이스들은 위의 메소드 특징에 따라서 5형태의 카테고리로 나뉜다.
추상 메소드의 특징으로 인터페이스를 고른 뒤, 전달한 인자의 종류에 따라서 구체적인 인터페이스를 골라 사용하면 된다.
java.util.function 오라클 DOC
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Doc문서에서 카테고리별로 정렬을 안해줘서, 보기가 좀 불편한데 인터페이스와 그 추상메소드는 굉장히 직관적이라 알기만 한다면 쉽게 사용할수 있다.
Cunsunmer
인자를 받고 메소드에서 리턴없이 소모시킨다.
인자만 다를 뿐 추상 메소드명은 전부 accept인 것이 특징이다.
인터페이스명 | 추상 메소드 | 설명 |
---|---|---|
Consumer |
void accept(T t) | 객체 T를 받아 소비 |
BiConsumer<T,U> | void accept(T t, U u) | 객체 T와 U를 받아 소비 |
DoubleConsumer | void accept(double value) | double 값을 받아 소비 |
intConsumer | void accept(int value) | int 값을 받아 소비 |
LongConsumer | void accept(long value) | long 값을 받아 소비 |
ObjDoubleConsumer |
void accept(T t, double value) | 객체 T와 double 값을 소비 |
ObjIntConsumer |
void accept(T t, int value) | 객체 T와 int 값을 받아 소비 |
ObjLongConsumer |
void accept(T t, long value) | 객체 T와 long 값을 받아 소비 |
아래처럼 간단히 값을 출력하는 함수를 만들때 사용할 수도 있다.
1 | package java_lamdba; |
Supplier
인자가 없으며 리턴값이 존재 한다.
리턴하는 값의 타입에 따라 getXXX형태의 추상메소드를 갖는 것이 특징이다.
인터페이스명 | 추상 메소드 | 설명 |
---|---|---|
Supplier |
T get() | T 객체를 리턴 |
BooleanSupplier | boolean getAsBoolean() | boolean 값을 리턴 |
DoubleSupplier | double getAsDouble() | double 값을 리턴 |
intSupplier | int getAsint() | int 값을 리턴 |
LongSupplier | long getAsLong() | long 값일 리턴 |
1 | package java_lamdba; |
Function
이 인터페이스의 용도는 인자의 타입을 변형하여 새로운 타입으로 값을 리턴하는 것이다.
즉 일종의 형변환 전용 함수형 인터페이스가 되겠다.
매개인자 타입과 리턴값의 타입이 다르다.
인터페이스명 | 추상 메소드 | 설명 |
---|---|---|
Function<T, R> | R apply(T t) | 객체 T를 객체 R로 매핑 |
BiFunction<T,U,R> | R apply(T t, U u) | 객체 T와 U를 객체 R로 매핑 |
DoubleFunction |
R apply(double value) | double을 객체 R로 매핑 |
intFunction |
R apply(int value) | int를 객체 R로 매핑 |
intToDoubleFunction | double applyAsDouble(int value) | int를 double로 매핑 |
intToLongFunction | long applyAsLong(int value) | int를 long로 매핑 |
LongToDoubleFunction | double applyAsDouble(long value) | long을 doube로 매핑 |
LongToIntFunction | int applyAsInt(long value) | long을 int로 매핑 |
ToDoubleBiFunction<T,U> | double applyAsDouble(T t, U u) | 객체 T와 U를 double로 매핑 |
ToDoubleFunction |
double applyAsDouble(T value) | 객체 T를 double로 매핑 |
ToIntBiFunction<T,U> | int applyAsInt(T t, U u) | 객체 T와 U를 int로 매핑 |
ToIntFunction |
int applyAsInt(T value) | 객체 T를 int로 매핑 |
ToLongBiFunction<T,U> | long applyAsLong(T t, u) | 객체 T와 U를 long으로 매핑 |
ToLongFunction |
long applyAsLong(T value) | 객체 T를 long으로 매핑 |
1 | package java_lamdba; |
Operator
Function과 동일한 형태의 applyXXX라는 메소드를 가지고 있다.
하지만 매개값의 타입변환의 역활보다 매개값을 이용하여 연산을 수생한 후 동일한 타입으로 리턴값을 제공하는 역할을 한다.
매개인자의 타입과 리턴값의 타입이 동일
인터페이스명 | 추상 메소드 | 설명 |
---|---|---|
BinaryOperator |
T apply(T t1, T t2) | 동일한 타입의 t1, t2를 연산후 T를 리턴 |
UnaryOperator |
T apply(T) | T를 연산한 후 T를 리턴 |
1 | package java_lamdba; |
인터페이스명 | 추상 메소드 | 설명 |
---|---|---|
DoubleBinaryOperator | double applyAsDouble(double, double) | 두개의 double 연산 후 double 리턴 |
DoubleUnaryOperator | double applyAsDouble(double) | 한 개의 double 연산후 double리턴 |
intBinaryOperator | int applyAsInt(int, int) | 두 개의 int 연산후 int 리턴 |
intUnaryOperator | int applyAsInt(int) | 한개의 int연산후 int리턴 |
LongBinaryOperator | long applyAsLong(long, long) | 두개의 long 연산후 long 리턴 |
LongUnaryOperator | long applyAsLong(long) | 한 개의 long 연산후 long리턴 |
Predicate
Prediacate는 매개 값을 이용하여 true, false를 리턴한다.
인터페이스명 | 추상 메소드 | 설명 |
---|---|---|
Predicate |
boolean test(T t) | 객체 T를 통해 boolean리턴 |
BiPredicate<T,U> | boolean test(T t, U u) | 객체 T와 U를 통해 통해 boolean리턴 |
DoublePredicate | boolean test(double value) | double 값을 통해 boolean리턴 |
intPredicate | boolean test(int value) | int값을 통해 boolean 리턴 |
LongPredicate | boolean test(long value) | long값을 통해 booean 리턴 |