내로그
람다식(Lambda) 본문
람다식이란?
람다식
함수(메소드)를 간단한 식으로 표현하는 방법
(타입 매개변수,...) -> { 실행문 }
표현방법
1. 메서드의 이름과 반환타입을 제거하고 -> 를 블록 {} 앞에 추가한다.
2. 반환값이 있는 경우 , 식이나 값만 적고 return 문 생략 가능 (끝에 ; 안 붙임)
3. 매개변수의 타입이 추론 가능하면 생략가능(대부분의 경우 생략가능)
4. 매개변수가 하나인 경우, 괄호() 생략 가능(타입이 없을때만)
5. 블록 안의 문장이 하나 뿐 일때, 괄호{} 생략가능(끝에 ; 안붙임)
단, 하나뿐인 문장이 return 문이면 괄호{} 생략뷸가
*람다식은 익명객체
자바는 람다식을 함수적 인터페이스(메소드를 1개만 가지고있는)의 익명 구현 객체로 취급
Runnable runnable = new Runnable(){
public void run(){...}
}
// 람다식
Runnable runnable = () -> {...}
타겟타입
-람다식이 대입되는 인터페이스
-익명 구현 객체를 만들 때 사용할 인터페이스
인터페이스(타겟타입) 변수 = 람다식;
함수적 인터페이스( functional interface )
- 하나의 추상 메소드만 선언된 인터페이스
@FunctionalInterface 어노테이션
-하나의 추상메소드만 가지는 컴파일러가 체크함
-두개 이상의 추상 메소드가 선언되어 있으면 컴파일 오류
@FunctionalInterface
public interface MyFunctionalInterface {
public void method();
}
public class MyFunctionalInterfaceTest {
public static void main(String[] args){
MyFunctionalInterface fi = () -> System.out.println("Hello");
fi.method();
}
}
클래스의 멤버 사용
-람다식 실행 블록에는 클래스의 멤버인 필드와 메소드를 제약 없이 사용할 수 있다.
-람다식 실행 블록내에서 this는 람다식을 실행한 객체의 참조이다.
public class ExampleTest {
public int outerField = 10;
class Inner {
int innerField =20;
void method(){
//람다식
MyFunctionalInterface fi = () -> {
// 바깥 객체 참조 클래스명.this
System.out.println("outerField: "+ ExampleTest.this.outerField);
// 람다식 내부 this 는 Inner 객체 참조
System.out.println("innerField: "+ this.innerField);
};
fi.method();
}
}
*로컬 변수의 사용
-람다식은 함수적 인터페이스의 익명 구현 객체를 생성한다.
-람다식에서 사용하는 외부 로컬 변수는 final 특성을 갖는다.
public class UsingLocalVariable {
void method(int arg){
int localVar = 40;
// arg , localVar 은 람다식에서 사용하고 있기 때문에 final 특성을 가짐
// 수정 불가
MyFunctionalInterface fi = () -> {
System.out.println("arg: "+ arg);
System.out.println("localVar: "+ localVar);
};
fi.method();
}
}
*한 개의 추상 메소드를 가지는 인터페이스들은 모두 람다식 사용 가능
public class LambdaExample {
public static void main(String[] args){
Runnable runnable = ()->{
for(int i=0; i<10; i++){
System.out.println(i);
}
};
// 1
Thread thread = new Thread(runnable);
thread.start();
//2
Thread thread2 = new Thread(()->{
for(int i=0;i<10;i++){
System.out.println(i);
}
});
}
}
Runnable 은 run() 이라는 하나의 추상메소드를 가지므로 람다식 사용 가능
*자바 8부터 표준 API로 제공되는 함수적 인터페이스
- Consumer : 매개값만 있고 리턴값이 없는 추상 메소드( accept() )를 가지고 있다.
- Supplier : 매개값은 없고 리턴값만 있는 추상 메소드( get() )를 가지고 있다.
- Function : 매개값과 리턴 값이 모두 있는 추상 메소드( apply() )를 가지고 있다.
주로 매개값을 리턴값으로 매핑(타입변환)할 경우에 사용
- Operator : 매개값과 리턴 값이 모두 있는 추상 메소드( apply() )를 가지고 있다.
주로 매개값을 연산하고 그 결과를 리턴할 경우 사용
- Predicate : 매개값을 조사해서 true 또는 false를 리턴할 때 사용( test() )
andThen() 과 compose() 디폴트 메소드
- 함수적 인터페이스가 가지고 있는 디폴트 메소드이다.
- 두개의 함수적 인터페이스를 순차적으로 연결해서 실행한다.
- 첫번째 리턴값을 두번째 매개값으로 제공해서 최종 결과값을 리턴한다.
- andThen() 과 compose()의 차이점은 어떤 함수적 인터페이스부터 처리하냐이다.
메소드 참조
- 메소드를 참조해서 매개변수의 정보 및 리턴타입을 알아내어
람다식에서 불필요한 매개변수를 제거하는 것이 목적이다.
- 기존 메소드를 단순하게 호출만 하는경우
( string ) -> System.out.println( string );
System.out :: println ----- 이렇게 표현하는게 메소드 참조다.
-메소드 참조도 람다식과 마찬가지로 인터페이스의 익명 구현 객체로 생성됨
타겟 타입에서 추상 메소드의 매개변수 및 리턴 타입에 따라 메소드 참조도 달라진다.
public class Calculator {
String name;
public static int staticAdd(int num1, int num2){
return num1+num2;
};
public int instanceAdd(int num1, int num2){
return num1 + num2;
};
public Calculator(String name){
this.name = name;
}
public static void main(String[] args){
IntBinaryOperator operator;
Function<String,Calculator> function = Calculator::new; // 생성자 참조
Calculator calculator = function.apply("참조");
operator = (num1,num2)->Calculator.staticAdd(num1,num2);
operator = Calculator::staticAdd; // static 메소드 참조
operator = (num1,num2)->calculator.instanceAdd(num1,num2);
operator = calculator::instanceAdd; // instance 메소드 참조
}
}
'WEB > Java' 카테고리의 다른 글
Java Stream(스트림) 중간처리, 최종처리 메소드 (0) | 2022.08.25 |
---|---|
Java Stream(스트림) 파이프라인 (0) | 2022.08.24 |
Java Stream(스트림) (0) | 2022.08.24 |