본문으로 바로가기

[자바]5. 람다(Lamda)

category Language/자바 2021. 4. 2. 21:37
728x90
반응형
SMALL

자바 8부터 람다식을 지원한다.

람다식은 익명 함수를 생성하기 위한 식으로 객제 지향 언어보다는 함수 지향 언어에 가깝다.

람다식을 사용하는 이유는❓

✏️자바 코드가 매우 간결해지고

✏️컬렉션의 요소를 필터링하거나 매핑해서 원하는 결과를 쉽게 집계할 수 있기 때문

 

⏳기존 Runnable 익명 구현 객체를 생성하는 코드

Runnable runnable=new Runnable(){
	public void run(){...}

};

 

⏳람다식 생성 코드

Runnable runnable=() -> {...};

 

 

✔️람다식 생성조건

✏️1.무조건 단 하나만의 추상 메소드가 선언된 인터페이스만 람다식의 타겟이 된다.

✏️2.@FunctionalInterface 어노테이션을 통해 두 개 이상의 추상 메소드가 선언되면 컴파일 오류를 발생시켜 확인할 수 있다.

@FunctionalInterface 
public interface MyFunctionalInterface {
	public void method();
	public void mehod(); //컴파일 오류

}

 

 

⏳매개 변수와 리턴값이 없는 람다식

package lamda;

@FunctionalInterface 
public interface MyFunctionalInterface {
	public void method();


}
package lamda;

public class MyFunctionalInterfaceExample {
	public static void main(String[] args) {
		MyFunctionalInterface fi;
		
		fi=() -> {
			String str="method call1";
			System.out.println(str);
		};
		fi.method();
		
		fi=() -> {System.out.println("method call2"); };
		fi.method();
		
		fi=() -> System.out.println("method call2"); 
		fi.method();
		
	}

}

3가지 방법으로 람다식을 표현하였다.

 

⏳매개변수가 있는 람다식

public interface MyFunctionalInterface {
	public void method(int x);
}
public class MyFunctionalInterfaceExample {
	public static void main(String[] args) {
		MyFunctionalInterface fi;
		
		fi=(x)->{
			int result=x*5;
			System.out.println(result);
		};
		fi.method(2);
		
		fi=(x)->{System.out.println(x*5);};
		fi.method(2);
		
		fi=x->System.out.println(x*5);
		fi.method(2);
	}

}

 

⏳리턴값이 있는 람다식

중괄호 {}에 return문만 있고, 혹은 return문 뒤에 연산식이나 메소드 호출이 오는경우 {}과 return 을 빼고 작성할수있다.

public interface MyFunctionalInterface {
	public int method(int x, int y);

}
public class MyFunctionalInterfaceExample {

	public static void main(String[] args) {
		MyFunctionalInterface fi;
		
		fi=(x,y)->{
			int result=x+y;
			return result;
		};
		System.out.println(fi.method(2, 5));
		
		fi=(x,y)->{return x+y;};
		System.out.println(fi.method(2, 5));
		
		fi=(x,y) -> x+y;
		System.out.println(fi.method(2, 5));
		
		fi=(x,y) -> sum(x,y);
		System.out.println(fi.method(2, 5));
		
		
	}

	private static int sum(int x, int y) {
		// TODO Auto-generated method stub
		return (x+y);
	}

}

 

 

✔️람다식의 로컬 변수 사용

람다식의 바깥 클래스의 필드나 메소드는 제한 없이 사용할 수 있으나 메소드의 매개 변수 또는 로컬 변수를 사용하면 

이 두 변수는 final 특성을 가져야 한다 why❓

매개 변수나 로컬 변수를 익명 객체에서 사용할 때,

🌈메소드 내에서 생성된 익명 객체는 메소드 실행이 끝나도 힙 메모리에 존재해서 계속 사용할 수 있으나 매개 변수나 로컬 변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 익명 객체에서 사용할 수 없게 된다, 이 때문에 final이 등장!

 

익명 객체 내부에서 메소드의 매개 변수나 로컬 변수를 사용할 경우, 이 변수들은 final 특성을 가져야 한다.

자바 7 이전까지는 반드시 final 키워드로 이 변수들을 선언했어야 하나 

자바 8 이후로는 final 없이 선언해도 된다. 허나 선언하지 않아도 값을 수정할 수 없는 final 특성을 갖는다.

💪🏻고로 익명 객체에서 사용된 매개 변수와 로컬 변수는 모두 final 특성을 갖는다는것만 알자

@FunctionalInterface 
public interface MyFunctionalInterface {
	public void method();


}
public class UsingLocalVariable {
	void method(int arg) { //arg는 final 특성을 가짐
		int localVar=40; // localVar는 final 특성을 가짐
		
		//arg=31;        final 특성 때메 수정 불가
		//localVar=41;   final 특성때메 수정 불가
		
		MyFunctionalInterface fi=()->{
			System.out.println("args: "+arg);
			System.out.println("localVar: "+localVar+"\n");
		};
		fi.method();
	}
	
}
public class UsingLocalVariableExample {

	public static void main(String[] args) {
		UsingLocalVariable ulv=new UsingLocalVariable();
		ulv.method(20);
		
	}

}
728x90
반응형
LIST