자바8강의 1강. lambda expression
TRANSCRIPT
Lambda expression
Javacafe 백엔드 스터디 (자바8)
목차
•동작 파라미터로 코드 개선하기
• Lambda - 문법
• Lambda - 함수형 인터페이스
•디폴트 메서드
• Lambda - 기본제공 함수형 인터페이스
• Lmabda - 형식검사, 추론, 제약
• Lmabda - 메서드 레퍼런스
•실전예제 - 로깅 람다로 개선하기
•실전예제 - 디자인패턴 람다로 변경하기
동작 파라미터로 코드 개선하기
과일 재고관리 애플리케이션을 개발사과를 필터링하여 보여줄 수 있는 기능을 요구
요구사항
150g이상인 사과만 필터링빨간사과와 초록사과를 분리하기빨간색이며 150g 이상인 사과를 필터링….….
동작 파라미터로 코드 개선하기
초록색 사과만 필터링하기
동작 파라미터로 코드 개선하기
색상을 파라미터로 받을 수 있도록 하기
동작 파라미터로 코드 개선하기
무게를 기준으로 필터링하기색상을 필터링하는 경우와 유사한 코드가 나타난다.
동작 파라미터로 코드 개선하기
조건을 파라미터로 직접 넣을 수 있도록 만들기
동작 파라미터로 코드 개선하기
사용시 다음과 같이 구성이 가능하다.
동작 파라미터로 코드 개선하기
ApplePredicate를 익명클래스로 구현
동작 파라미터로 코드 개선하기
익명클래스를 람다로 변환하기 - 1
동작 파라미터로 코드 개선하기
익명클래스를 람다로 변환하기 - 2
동작 파라미터로 코드 개선하기
람다 활용예 - Comparator
동작 파라미터로 코드 개선하기
람다 활용예 - Runnable
Lambda - 문법
https://ko.wikipedia.org/wiki/람다_대수
Lambda - 문법
Lambda - 문법
람다의 특성
● 익명○ 보통의 메서드와는 달리 이름이 없다.
● 함수○ 람다는 메서드처럼 특정 클래스에 종속되지 않는다.파라미터 리스트, 바디, 반환 형식을 포함한다.
● 전달○ 람다 표현식을 메서드 인수로 전달하거나 변수로 저장할 수 있다.
● 간결성○ 익명 클래스처럼 많은 부가 코드를 구현할 필요가 없다.
Lambda - 문법
Lambda - 함수형 인터페이스
● 하나의 추상 메서드를 가진 인터페이스만 람다로 사용할 수 있다. 이러한 인터페이스를 함수형 인터페이스라고 한다.
● 인터페이스 내부에 선언된 유일한 메서드에 람다의 몸체가 정의된다.
● 함수형 인터페이스에 디폴트 메서드가 여럿 있더라도, 추상 메서드가 하나라면 함수형 인터페이스이다.
● 어노테이션 @FunctionalInterface를 클래스 상단에 붙여 명시적으로 함수형 인터페이스라는 것을 표기해줄 수 있다.
Lambda - 함수형 인터페이스
• 람다는 결과적으로 함수형 인터페이스가 가지는 유일한 메서드가 구현되는 것이다. (이를 바탕으로 타입 추론이 가능)
• 함수형 인터페이스를 인자로 가지는 게스트 코드 입장에서는 코드가 인스턴스화 되어 인자로 들어오므로 호스트 코드에서 보내는 인스턴스의 정체가 람다인지 익명클래스인지는 관심이 없다.
• 람다와 익명클래스는 다르다.– 익명클래스는 컴파일시 서브클래스로 별도의 파일로 컴파일되고 람다는 기존 클래스에 포함된다.
– 람다는 바이트코드로 변환시 Java7에서 추가된 InvokeDynamic 명령어을 이용하여 런타임에 코드가 생성된다.
Lambda - 함수형 인터페이스
• 함수형 인터페이스를 인자로 받는 메소드에만 람다식을 사용할 수 있다.– 새로운 함수형을 추가할 경우 언어가 더 복잡해진다.– 대부분의 자바 프로그래머가 익명클래스 문법에 익숙하다.
• 위와 같은 제약사항으로 인해 람다식의 타입 추론이 가능해졌다.– 함수형 인터페이스가 가지고 있는 추상 메소드가 오직 하나 밖에 없으므로 이를 이용하여 타입 추론
– 람다식의 Prameter 추론 : 추상 메소드의 파라메터 정보– 람다식의 Return 타입 추론 : 추상 메소드의 리턴 타입 정보
• Java8에서는 java.util.function 패키지로 다양한 함수형 인터페이스를 제공한다.
디폴트 메서드
default 키워드를 사용하면 인터페이스에 메서드를 바로 설정 가능기존의 구현체 구조를 변경하지 않고도 새로운 기능을 추가 할 수 있다.
<Interface>List
ArrayList
LinkedList
Stack
ArrayList
LinkedList
Stack
Java.util.function 패키지
Lambda - 기본제공 함수형 인터페이스
Predicate<T> T -> boolean
• Java.util.function.Predicate<T>– 추상메소드 test()를 람다의 바디에서 정의– T타입을 인수로 받아 Boolean을 리턴
• 입력값 T가 어떤 조건을 충족하는지 여부를 확인하는 메서드• 어떤것이 사실인지 아닌지를 리턴해주는 람다식이 바디로 정의
Lambda - 기본제공 함수형 인터페이스
Predicate<T> T -> boolean
Lambda - 기본제공 함수형 인터페이스
Consumer<T> T -> void
• Java.util.function.Consumer<T>– 추상메소드 accept()를 람다의 바디에서 정의– T타입을 인수로 받고 리턴하지 않음
• 입력값 T를 받아 어떠한 동작을 수행시키는 메서드• 람다의 바디는 특정 동작을 수행하며 반환값이 없는 형태.
Lambda - 기본제공 함수형 인터페이스
Consumer<T> T -> void
Lambda - 기본제공 함수형 인터페이스
Function<T, R> T -> R
• Java.util.function.Function<T, R>– 추상메소드 apply()를 람다의 바디에서 정의– T타입을 인수로 받아 R타입을 리턴
• 입력값 T를 출력값 R로 변환시키는 메소드• 입력값을 출력값으로 매핑하는 로직이 람다의 바디에 정의된다.
Lambda - 기본제공 함수형 인터페이스
Function<T, R> T -> R
Lambda - 기본제공 함수형 인터페이스
Supplier<T> () -> T
• Java.util.function.Supplier<T>– 추상메소드 get()를 람다의 바디에서 정의– 인수없이 T 객체를 리턴
• 정해진 T를 공급하는 메서드• 입력값이 없으며 람다식에 정의된 값을 결과로 반환한다.
Lambda - 기본제공 함수형 인터페이스
Supplier<T> () -> T
Lambda - 기본제공 함수형 인터페이스
람다 표현식 조합
• Java.util.function 패키지에서 제공하는 함수형 인터페이스 중 일부는 static 메소드 형태의 유틸리티 메소드를 가지고 있다.– Predicate– Function
• 유틸리티 메서드를 조합해서 복잡한 로직을 보다 간결하게 표현할 수 있다.
Lambda - 기본제공 함수형 인터페이스
Lambda - 기본제공 함수형 인터페이스
Lambda - 기본제공 함수형 인터페이스
Lambda - 기본제공 함수형 인터페이스
오토박싱 비용을 줄일수 있도록 Java8은 기본형 특화 함수형 인터페이스를 제공한다.
Lambda - 메서드 레퍼런스
람다를 간결하게 쓸 수 있도록 도와주는 문법클래스(객체)명과 메서드명 사이에 구분자(::)를 붙여 사용한다.
Lambda - 메서드 레퍼런스
종류 형식
정적 메서드 참조 클래스명::정적메서드명
객체 메서드 참조 객체변수::메서드명
람다인자 객체 메서드 참조
클래스명::메서드명
생성자 참조 클래스명::new
메서드 레퍼런스의 종류
Lambda - 메서드 레퍼런스
정적 메서드 참조
Function<String, Integer> toNumber1 = (str) -> Integer.parseInt(str);
Function<String, Integer> toNumber2 = Integer::parseInt;
• 클래스 내부에 정의된 정적메서드 호출을 표현할 수 있다.
– (인자) -> 클래스.정적메서드(인자)
– 클래스::정적메서드
Lambda - 메서드 레퍼런스
객체 메서드 참조
• 객체의 인스턴스 메서드 호출을 표현할 수 있다.
– (인자) -> 객체.인스턴스메서드(인자)
– 객체::인스턴스메서드
Consumer<String> out1 = (str) -> System.out.println(str);
Consumer<String> out2 = System.out::println;
Comparator<Integer> comp1 = (o1, o2) -> o1.compareTo(o2);
Comparator<Integer> comp2 = Integer::compareTo;
Lambda - 메서드 레퍼런스
람다인자 객체 메서드 참조
• 람다인자객체의 인스턴스 메서드 호출을 간결하게 표현
– (인자1, 인자2) -> 인자1.메서드(인자2)
– 인자1의클래스명::메서드명
Lambda - 메서드 레퍼런스
생성자 참조
• 클래스의 생성자를 간결하게 호출할 수 있다.
– (인자) -> new 클래스(인자), () -> new 클래스()
– 클래스::new
Supplier<String> int1 = () -> new String();
Supplier<String> int2 = String::new;
Stream?!?!!
Stream!!!!!
요약
● 람다 표현식은 익명클래스를 간결하게 표현할 수 있다.(약간은 달라요.)
● 함수형 인터페이스는 하나의 추상 메서드만이 정의된 인터페이
스
● 자바에서는 자주 사용되는 기본적인 형태의 함수형 인터페이스
를 제공
● 기본제공되는 함수형 인터페이스는 Boxing을 피할 수 있도록 IntPredicate, IntToLongFunction과 같은 primitive타입의 인터페이스 제공
● 메서드 레퍼런스를 이용하면 기존의 메서드 구현을 재사용 및 전
달 가능
● Comparator, Predicate, Function 같은 함수형 인터페이스는람다 표현식을 조합할 수 있는 다양한 디폴트 메서드를 제공