상세 컨텐츠

본문 제목

15주차 과제: 람다식

자바 스터디

by ENOTHFIF 2021. 3. 6. 21:18

본문

목표

자바의 람다식에 대해 학습하세요.

학습할 것 (필수)

  • 람다식 사용법
  • 함수형 인터페이스
  • Variable Capture
  • 메소드, 생성자 레퍼런스

 


람다식(Lamda Expression)이란?

  • 메서드를 하나의 식(expression)으로 표현한 것이다.

람다식 사용법

  • 실행문이 한 줄일 경우
    (매개변수...) -> 실행문
  • 실행문이 여러 줄일 경우
    (매개변수...) -> {

            실행문1
            실행문2
    }
  • 메서드에서 이름과 반환타입을 제거하고 매개변수 선언부와 몸통{} 사이에 '->'를 추가한다.
  • return문 대신 식으로 대신할 수 있다.(이때는 문장이 아닌 식이므로 세미콜론을 붙이지 않는다.)
  • 람다식에 선언된 매개변수의 타입은 추론이 가능한 경우 생략할 수 있다.

메서드

람다식

int max(int a, int b) {

      return a > b ? a : b;

}

(int a, int b) -> { return a > b ? a : b; }

(int a, int b) -> a > b ? a : b

(a, b) -> a > b ? a : b

 

함수형 인터페이스(Functional Interface)

  • 람다식을 다루기 위한 인터페이스이다.
  • 단 한개의 추상 메서드만 정의되어 있어야한다. (람다식과 인터페이스의 메서드가 1:1로 연결)
  • @FunctionalInterface를 붙이면, 컴파일러가 함수형 인터페이스를 올바르게 정의하였는지 확인해주므로, 반드시 작성하도록 한다.
public class LambdaTest {	

	@FunctionalInterface
	interface TestFunction{
		
		public abstract void test();
	}
	
	public static void main(String[] args) {
		
		TestFunction f = () -> System.out.println("테스트");
		f.test();
	}
}

 

익명 내부 클래스와의 비교

public class LambdaTest {	

	@FunctionalInterface
	interface TestFunction{
		
		public abstract void test();
	}
	
	public static void main(String[] args) {
		TestFunction f = new TestFunction(){
			@Override
			public void test() {
				System.out.println("테스트");
			}
		};
		f.test();
	}
}
  • 람다식을 사용하는 편이 코드가 간결하고 구현이 쉽다.

Variable Capture

  • 람다식은 외부에서 정의된 변수(자유변수, free variable)를 사용할 수 있는데 이런 람다 바디에서 자유변수를 참조하는 행위를 Lambda capturing이라고 한다.
  • 단, 외부에서 정의된 free variable는 final 이거나 final 속성(재할당X)을 띄어야한다.

람다식 내에서 외부에 선언된 변수에 접근하는 방법

@FunctionalInterface
interface Test{
	public abstract void method();
}

public class Capture {

	public static void main(String[] args) {
		
		int a = 1;
		
		Test t = () -> {
			a = 30;//에러
			System.out.println("a="+a);
		};
		t.method();
	}
}

 

 

메소드 참조

메소드 참조는 람다 표현식이 단 하나의 메소드 만을 호출하는 경우에 해당 람다 표현식에서 불필요한 매개변수를 제거하고 사용할 수 있도록 해준다.

메서드 참조 기본 문법
(Object name)::(Method name)
import java.util.function.*;

public class Prog {
	public static void main(String[] args){
		DoubleUnaryOperator oper;
		
		oper = (n) -> Math.abs(n);	// 람다 표현식
		System.out.println(oper.applyAsDouble(-5));
		
		oper = Math::abs;			// 메소드 참조
		System.out.println(oper.applyAsDouble(-5));
	}
}

 

생성자 참조

생성자를 호출하는 람다 표현식도 앞서 살펴본 메소드 참조를 이용할 수 있다

즉, 단순히 객체를 생성하고 반환하는 람다 표현식은 생성자 참조로 변환할 수 있습니다.

 

객체를 생성하고 반환하는 람다 표현식

(a) -> { return new Object(a); }

위의 예제를 생성자 참고를 사용하여 변경

Object::new;

 

 

참고자료

- 자바의 정석 3판

- 코드를 통해 본 빵형의 실전 Java

https://perfectacle.github.io/2019/06/30/java-8-lambda-capturing/

 

(Java) 람다 캡처링과 final 제약조건

람다의 바디에서는 파라미터 말고 바디 외부에 있는 변수를 참조할 수 있다. 1234567891011public class LambdaCapturing { private int a = 12; public void test() { int b = 123; final Runnable r = () -> S

perfectacle.github.io

https://tourspace.tistory.com/6

 

Java 8 Lambda Expression - 람다식 #3

이미 #1,#2에서 람다가 어떻게 활용되는지 먼저 봤습니다. 여기서는 람다의 정의와 FunctionalInterface에 대해서 얘기합니다. 람다(Lambda)란? 람다는 이름없는 함수입니다. 말하자면 익명함수(Anonymous Fu

tourspace.tistory.com

http://www.tcpschool.com/java/java_lambda_reference

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com