람다식

이재연·2021년 4월 15일
0

Java Basic

목록 보기
15/15
post-custom-banner

람다 표현식이란?

메소드를 식으로 표현한 것이다. 메소드를 단순하게 표현한 것이다. 익명 함수라고도 부른다.

(파라미터) -> {메소드 구현}
() -> {메소드 구현}
(파라미터) -> 메소드 구현
(파라미터) -> {return 결과;}
  • 자바에서의 람다식

내부에 추상 메소드가 하나만 있는 interface를 사용한다.

일급 객체(First-class Citizen)의 특성을 가진다.

  • 일급 객체 특징
  1. 변수에 할당할 수 있다.
  2. 파라미터로 사용할 수 있다.
  3. 리턴값으로 사용할 수 있다.

람다식 사용법

내부에 구현된 추상 메소드를 클래스로 구현하지 않고 사용 할 수 있다.

public interface MyFoo{
	public int myFunction(int a, int b);
}

-> 를 사용해 표현한다.

(파라미터)->{메소드 구현} 형태로 사용한다.

메소드 구현이 1줄인 경우 블록을 생략 할 수 있다.

public static void main() {
	MyFoo mf1 = (a, b) -> {
		System.out.println(a + "+" + b);
		return a + b;
		};

	//블록 생략
	MyFoo mf2 = (a, b) -> a + b;
}

함수형 인터페이스

내부에 추상 메소드가 하나만 있는 interface를 함수형 인터페이스라고 부른다.

@FunctionalInterface애노테이션을 사용하면 컴파일 단계에서 문제를 확인 할 수 있다.

2개 이상의 추상 메소드를 선언하면 컴파일 에러가 발생한다.

Variable Capture

람다는 변수를 사용 할 때 내부적으로 값을 복사해서 사용한다. 왜 이런 방식을 사용할까?

우선 람다를 사용하면 익명 구현 객체를 사용하는 것과 비슷한 방식으로 동작한다. 정확히 내부 구현은 다르지만 힙 영역에 저장된다. 반면 지역 변수는 스택 영역에 저장된다. 그리고 메소드 실행이 끝나면 스택 영역에서 사라진다.

힙 영역에 있는 람다가 변수를 사용하려고 할 때 이 변수가 스택 영역에서 사라져있으면 변수를 사용하지 못하게 된다. 그래서 람다는 값을 복사해서 사용하는 것이다.

근데 람다를 사용하다 보면 final 변수만 사용할 수 있다. 이는 또 왜 그런걸까?

만약 다른 쓰레드에서 이 변수의 값을 변경하게 되면 정확하지 않은 결과가 나올 수 있다. 그렇기 때문에 동시성 문제를 위해 final 변수만 사용하는 것이다.

지역변수는 final이 아니기 때문에 컴파일 에러가 발생하고 인스턴스 변수는 제한 없이 사용 가능하다.

메소드, 생성자 레퍼런스

메소드, 생성자 레퍼런스는 람다를 더욱 간략하게 표현할 수 있게 해준다.

메소드를 하나만 호출하는 경우 메소드 레퍼런스를 사용하면 더 간략하게 표현 할 수 있다.

:: 를 사용한다.

@FunctionalInterface
public interface MyFoo {
	public int myFunction(String s);
}
public static void main() {
	MyFoo mf1 = (s)	-> Integer.parseInt(s);
	//메소드 레퍼런스 사용
	MyFoo mf2 = Integer::parseInt;
}

생성자 레퍼런스도 같은 방식으로 사용한다.

public class MyInstance {
	public String s;
	
	public MyInstance(String s) {
		this.s = s;
	}
}
@FunctionalInterface
public interface MyFoo {
	public MyInstance myFuntion(String a);
}
public static void main() {
	MyFoo mf1 = (s)	-> new MyInstance(s);
	//생성자 레퍼런스 사용	
	MyFoo mf2 = MyInstance::new;
}

참조

https://docs.oracle.com/javase/specs/jls/se10/html/jls-15.html#jls-15.27.2

post-custom-banner

0개의 댓글