What is Lambda?
람다란? 메서드를 하나의 식
으로 표현한 것. 익명함수 (Anonymous functions)와 같다.
사용방법
1
2
3
4
5
6
7
8
9
10
11
//평문
int max(int a, int b){
return a>b ? a : b;
}
//람다 (타입이 추론 가능할때 생략가능)
(a,b) -> { return a > b ? a : b;} //리턴일때는 중괄호 생략 불가
그밖에
(int a) -> a*a; = a-> a*a; //매게변수 괄호 생략가능
(String name, int i) -> System.out.println(name+"="+i) //중괄호 생략가능
함수형 인터페이스 (@functional interface)?
함수형 인터페이스는 람다식을 다루기 위한 인터페이스이다. 오직 하나의 추상 메서드만 정의
되어 있어야 한다는 제약이 있다.
그래야 람다식과 인터페이스의 메서드가 1대1로 연결된다.
※ @FunctionalInterface는 컴파일러가 함수형 인터페이스를 올바르게 정의했는지 확인해주는 어노테이션이다.
1
2
3
4
5
6
7
@FunctionalInterface
interface Function{
public abstract int max(int a , int b);
}
============================================
Function f = (int a, int b) -> a>b ? a : b;
int value = f.max(5,3);
java.util.function
일반적으로 자주 쓰이는 형식의 메서드를 함수형 인터페이스로 미리 정의해놓은 패키지이다.
주요 함수형 인터페이스
함수형 인터페이스 | 메서드 | 설명 |
---|---|---|
java.lang.Runnable | void run() | 매개변수 X 반환값 x |
Supplier | T get() | 매개변수 X 반환값 O |
Consumer | void accept(T t) | 매개변수 O 반환값 X |
Function<T,R> | R apply(T t) | 매개변수O 반환값 O (일반적인 메서드) |
Predicate | boolean test(T t) | 매개변수 하나 반환값 boolean (조건식 표현) |
1
2
3
4
5
6
7
8
9
10
Predicate<String> some = s -> s.length() == 0;
String s ="";
if(some.test(s)) // if(s.length()==0)랑 같다
sout("비어있다")
Supplier<Integer> s = ()-> (int)(Math.random()*100)+1;
Consumer<Integer> c = i ->System.out.print(i);
Function<Integer,Integer> f = i -> i/10*10; // 일의자리 삭제하기
Predicate<Integer> p = i%2 == 0;
이를 이용해서 다양한 함수를 사용할 수 있다.
매게변수가 두 개인 함수형 인터페이스
함수형 인터페이스 | 메서드 | 설명 |
---|---|---|
BiConsumer<T,U> | void accept(T t, U u) | 두개의 매개변수 반환값 x |
BiPredicate<T,U> | boolean test(T t, U u) | 두개의 매개변수 반환값 boolean |
BiFunction<T,U,R> | R apply(T t, U u) | 두개의 매개변수 반환값 O |
Function의 변형
함수형 인터페이스 | 메서드 | 설명 |
---|---|---|
UnaryOperator | T apply(T t) | function의 자손 |
BinaryOperator | T apply(T t, T t) | BiFunction의 자손 |
컬랙션 프레임워크 함수형 인터페이스
인터페이스 | 메서드 | 설명 |
---|---|---|
Collection | boolean removelf(Predicate | 조건에 맞는 요소를 삭제 |
List | void replaceAll(UnarOperator | 모든요소를 반환하여 대체 |
Iterable | void forEach(Consumer | 모든 요소에 작업 action을 수행 |
Map | V compute(K key, BiFunction<K,V,V>f) | 지정된 키의 값에 작업 F를 수행 |
V computeIfAbsent(K key, Function<K,V>f) | 키가 없으면 작업 f를 수행 | |
V computeIfPresent(K key, BiFunction<K,V,V>f) | 지정된 키가 있을 떄, 작업 f를 수행 | |
V merge((K key, V value, BiFunction<K,V,V>f)) | 모든 요소에 치환작업 병합작업 f를 수행 | |
void forEach(BiConsumer<K,V> action) | 모든 요소에 치환작업 작업 action을 수행 | |
void replaceAll(BiFunction<K,V,V> f) | 모든 요소에 치환작업 f를 수행 |
1
2
3
4
5
6
7
//list에 {1,2,3,4,5,6,7,8,9,10} 있다고 가정
//map에는 [1,1],[2,2],[3,3]
list.forEach(i-> sout(i + " ")); //{1,2,3,4,5,6,7,8,9,10}
list.removeIf(x-> x%2==0 || x%3==0); //{1,5,7}
list.replaceAll(x->x*10); //{10,20,30,40,50,60,70...}
map.forEach((k,v)->sout(k+" "+v))// 1 1 2 2 3 3
메서드 참조
람다식이 하나의 메서드만 호출하면 더 간단히 사용할 수 있다.
종류 | 람다 | 메서드 참조 |
---|---|---|
Static 메서드 참조할 경우 | (x)->className.method(x) | className::method |
인스턴스 메서드 참조할 경우 | (obj,x)->obj.method(x) | className::method |
특정 객체 인스턴스메서드 참조할 경우 | (x)->obj.method(x) | obj::method |
하나의 메서드만 호출하는 람다식은
클래스명::메서드명
or참조변수::메서드명