티스토리 뷰

프로그램이야기

6. 람다이야기 2

따강아지 2022. 6. 14. 00:29

JAVA 제너릭 함수형 인터페이스(Predicate <T>, Consumer <T>, Function <T, R>은 참조 형만 사용할 수 있다. 기본형을 참조형으로 변환(박싱 :boxing), 참조형을 기본형으로 변환(unboxing) 이것을 자동으로 하는 오토 박싱(autoboxing)이라 하는데 Java8에서는 다음과 같은 함수형 인터페이스를 제공한다.

함수형인터페이스 함수디스 기본형 설명
Predicate<T> T->boolen IntPredicate
LongPredicate
DoublePredicate
기본형을 받은 후 boolean 리턴
Consumer<T> T->void IntConsumer
LongConsumer
DoubleConsumer
기본형을 받은 후 소비
Function <T, R> T -> R IntToDoubleFunction
IntToLongFunction
LongToDoubleFunction
LongToIntFunction
DoubleToIntFunction
DoubleToLongFunction
기본형을 받아서 기본형 리턴
IntFunction<R>
LongFunction<R>
DoubleFunction<R>
기본형을 받아서 R 타입 리턴
ToIntFunction<T>
ToDoubleFunction<T>
ToLongFunction<T>
T 타입 받아서 기본형 리턴
Supplier<T> ()->T BooleanSupplier
IntSupplier
LongSupplier
DoubleSupplier
아무것도 받지 않고 기본형 리턴
UnaryOperator<T> T->T IntUnaryOperator
LongUnaryOperator
DoubleUnaryOperator
 
BinaryOperator<T> (T, T) -> T IntBinaryOperator
LongBinaryOperator
DoubleBinaryOperator
 
BiPredicate<T, U> (T, U)->boolen   2개의 인자를 받고 boolean을 리턴
BiConsumer<T, U> (T, U)->void ObjIntConsumer<T>
ObjLongConsumer<T>
ObjDoubleConsumer<T>
 2개의 인자를 받고 리턴 값이 없음
BIFunction<T,U,R> (T, U)->R ToIntBIFunction<T>
ToLongBIFunction<T>
ToDoubleBIFunction<T>
BiFunction은 2개의 인자(Type T, U)를 받고 1개의 객체(Type R)를 리턴

1.  형식 검사

람다가 사용되는 Context를 이용해서 람다의 Type을 추론한다.

List <Customer> customer = filter(customers, (Customer c) -> c.getAge() > 30 );

에서 (Customer c) -> c.getAge() > 30를 Predicate<Customer>으로  Predicate<T>로 boolean형을 의미한다

2.  형식 추론 

람다에서 사용되는 Context을 이용해서 관련된 함수형 인터페이스를 추론 하는 것을 의미한다.

Predicate <Customer> p = (Customer c) -> c.getAge() > 30;  //  형식 추론을 하지 않음 
List customer = filter(customers, p);

Predicate<Customer> p = (c) -> c.getAge() > 30;   // 형식 추론함 
List customer = filter(customers, (c) -> c.getAge() > 30 );

3.  지역변수

람다 외부에서 사용한 변수(Free Variable: 파라미터로 전달받은 변수가 아닌 변수)를 람다 표현식에서 사용할 때 인스턴스 변수, 정적 변수는 람다 표현식에 사용 할 수 있지만 지역변수 final로 선언하거나 final과 같은 수준의 변수 이어야 한다.

String company = "현대";
company = company + 1;
Predicate<Car> p = car -> car.getCompany().equals(company); // compile 오류

지역 변수는 stack에 위치하므로 thread에서 실행하면 지역 변수가 할당된 thread에서만 유효하기 때문이다.

4.  메서드 참조

람다를 보다 더 간결히 사용하고자 할 때 사용하는 것으로 특정 메서드만을 호출하는 라다의 축약형이다 

메서드 참조 유형 예 같은 기능을 하는 람다

정적 Integer::parseInt str -> Integer.parseInt(str);
한정적(인스턴스) Instant.now()::isAfter Instant then = Instant.now;
t -> then.isAfter(t)
비한정적(인스턴스) String::toLowercase str -> str.toLowerCase();
클래스 생성자 TreeMap<K,V>::new
Car :: new
() -> new TreeMap<K,V>();
() -> new Car()
배열 생성자 int[]::new len -> new int[len]