람다식(lambda expression)
-자바에서 클래스를 생성하지 않고 함수의 호출로 기능을 수행한다.
-외부값을 건드리지 않고(사이드이펙트가 없다.), 주어진 매개변수로 결과를 리턴한다.
//Before
int add(int x, int y){
return x+ y;
}
//After
(int x, int y) -> {return x+y;}
@FunctionalInterface
@FunctionalInterface // 함수형인터페이스, 이 어노테이션이 있으면 여러개의 메서드를 선언하면 에러가 난다.
Public interface MaxTest{
Int getMax(int x, int y); // 인터페이스 구현부 1개 선언해야함.
//더 추상 메서드를 선언하지 않는다.
}
.
.
.
MaxTest maxNum = (x,y) -> (x>=y)? x:y; // 함수가 여러개면 여기가 에러날 것임. 어떤 메서드 호출인지 모호해지니깐.
Int max = maxNum.getMax(10,5);
// max = 10
- 추상메서드는 딱 1개만 존재해야 한다.
Interface Print{
Void printString(string str);
}
Public class Test{
Public static void main(String[] args){
//1.변수로 implementation 하는 방법
Print test = str -> system.out.println(str);
test.printString(“str”); // str 출력됨
//2.implementation한 내용을 매개변수로 넘기는 방법
printLamda(test); // hi 출력
//3.implementation자체가 반환값으로 넘기는 방법
Print return = returnPrint();
return.printString(“return”);
}
Public static void showlamda(Print lamda){ // 함수 자체가 매개변수로 넘어갈 수 있다는 점.
Lamda.printString(“hi”);
}
//3.
Public static void Print returnPrint(){
Return s->system.out.println(s);
}
}
#함수를 변수처럼 사용할 수 있다.
interface PrintTest{
void printString(String str)
}
//함수형 인터페이스를 선언하고
void main(){
//내용을 설정해주고
PrintTest prinTest = str -> System.out.println(str);
printTest.printString("hello world!"); //사용하면 된다.
}
함수형 프로그래밍의 특징
#순수함수
//'추상'메서드가 하나만 있으면 함수형 인터페이스다.
//다른 메소드들이 있어도 추상 메서드가 1개면 함수형 인터페이스다.
@FunctionalInterface
Public interface Test{
void testFunc ();
static void test2(){
System.out.println("test2");
}
}
//이런식으로 함수가 더 있어도 Test interface는 함수형 인터페이스다.
//추상메서드는 1개기 때문.
//활용?
public static void main(String[] args){
Test test = new Test(){
@Override
public void testFunc(){
System.out.println("test");
}
}
}
// 이렇게 줄여 써도 같다.
public static void main(String[] args){
Test test = () -> System.out.println("test");
test.testFunc(); //이렇게 실행한다.
}
}
그리고 내부 지역변수 값이 변환되면 안되기때문에,
interface안에 변수를 선언하고 싶다면final 변수를 선언하지 않으면 에러가 날것.
@FunctionalInterface 어노테이션이 있으면 알아서 컴파일 에러가 뜰 것
pure function 순수함수라는 특징
#람다함수 매개변수 변수명 주의점 #내부 변수명과 이름을 같게 하면 안된다.
람다함수같은 경우에는
동일한 이름의 변수를 같이 공유한다. 즉, 인자값으로 같은 이름을 쓸 수 없다.
example.
num이라는 내부 변수가 있을 때, 같은 스코프에서 사용한다고 보면 된다. 그래서 람다함수에 i라는 변수명을 사용할 때는 정상적으로 사용 할 수 있다.
public void test(){
int num =10;
IntConsumer printInt = (i) -> {
System.out.println(num);
}
printInt.accept(10);
}
이와 같이 num이라는 같은 이름의 변수를 또 정의할 수는 없다.
//불가능한 케이스
public void test(){
int num =10; //num은 람다가 감싸고 있는 scope와 같은 scope라고 보면 된다.
IntConsumer printInt = (num) -> { // num이라는 같은 이름의 변수를 또 정의할 수는 없다.
System.out.println(num);
}
printInt.accept(10);
}
#메서드 레퍼런스 # :: 콜론 2개면
public class Greeting{
public static String hello(string name){
return "hello " + name;
}
}
//이런 클래스의 함수가 존재하는데
//같은 기능을 구현할 때
void main(){
UnaryOperator<String> hello = (s) -> "hello "+ s;
}
// 이렇게 대치될 수 있다.
void main(){
UnaryOperator<String> hello = Greeting::hi;
System.out.println(hello.apply("test"));
}
void main(){
Function<String, Greeting > greetingObj = Greeting::new; //생성자 참조도 가능
Greeting t1 = greetingObj.apply("name");
System.out.println(t1.getName());
}
'DEV > JAVA' 카테고리의 다른 글
java8 default 메소드, 스태틱 메소드 (0) | 2022.03.20 |
---|