2 분 소요

1. 람다식이란

람다식은 자바에서 함수형 프로그래밍 (functional programming)을 구현하는 방식입니다.

클래스를 생성하지 않고 함수의 호출만으로 기능을 수행하며,
함수형 인터페이스를 선언합니다.

여기서 함수형 프로그래밍이란,

  • 함수를 베이스로한 프로그래밍
  • 매개변수를 받아서 그 매개변수를 이용해서 프로그램을 하게 되면 외부 변수 사용을 하지않음
    (순수 함수형 프로그래밍)
  • 외부 변수를 사용하지 않기 때문에 외부에 부수적인 영향(side effect)를 주지 않음
  • 입력받은 자료를 기반으로 수행되고 외부에 영향을 미치지 않으므로
    병렬처리가 가능하며 안정적이고 확장성 있는 프로그래밍 방식

입니다.

내부적으로는 익명객체를 생성합니다.

2. 람다식 문법

  1. 매개변수가 하나인 경우 괄호 생략이 가능합니다. (두개인 경우 생략 불가능)

    str -> {System.out.println(str);}
    

    위에서 보듯이 함수의 이름이 없기 때문에 익명함수라는 것을 알 수 있습니다.
    -> 오퍼레이터는 앞에 매개변수를 이용해 뒤의 문장을 수행한다는 의미입니다.

  2. 중괄호 안의 구현부가 한 문장인 경우 중괄호 생략이 가능합니다.

    str -> System.out.println(str);
    
  3. 중괄호 안의 구현부가 한 문장이라도 return문은 중괄호 생략이 불가능합니다.

    str -> return str.length(); //오류
    
  4. 중괄호 안의 구현부가 반환문 하나라면 return문과 중괄호 모두 생략이 가능합니다.

    (x,y) -> x+y //두 값을 더하여 반환
    str -> str.length() //문자열 길이를 반환
    

3. 함수형 인터페이스

함수형 인터페이스는 람다식을 선언하기 위한 인터페이스입니다.

익명함수와 매개변수만으로 구현되므로 단 하나의 메서드만을 선언해야합니다.
(두개 이상의 메서드가 선언되면 어느 메서드의 호출인지 모호해짐)

@Fuctional Interface 애노테이션을 사용합니다.
(람다식을 위한 인터페이스라는 애노테이션)

원래는 어떤 인터페이스가 있고 그 인터페이스의 메서드를 호출한다 라고 하면
인터페이스를 구현한 클래스를 만들고 그 클래스의 인스턴스를 생성하고 참조변수를 통해 호출했습니다.

예시를 보겠습니다.
두개의 수 중 큰 수를 구하는 코드입니다.

//MyMaxNumber.java

@FunctionalInterface
public interface MyMaxNumber {
	int getMaxNumber(int x, int y);
} //메서드를 선언하기 위해 인터페이스를 사용

위 코드에서 만약 void add(int x, int y)라는 함수가 하나 더 작성됐다고 가정합시다.
이런 상황에서 람다식을 사용하면 x, y를 두개의 함수가 모두 사용하기 때문에 어떤 것을 사용할지 모호해집니다.

//TestMyNumber.java

public class TextMyNumber {
	public static void main(String[] args) {

		MyMaxNumber max = (x,y) -> (x>=y)?x:y;
    //메서드를 구현
		System.out.println(max.getMaxNumber(10,20));
    //사용
	}
}

두번째 예시를 보겠습니다.

람다식을 위한 함수형 인터페이스

@FunctionalInterface
public interface StringConcat {
	public void makeString(String s1, String s2);
}

원래 람다식을 이용하지 않을 때

public class StringConImp1 implements StringConcat{

	@Override
	public void makeString(String s1, String s2) {
		System.out.println (s1 + "," + s2);
	}
}
public class TestString {

	public static void main(String[] args) {

		StringConImp1 imp1 = new StringConImp1();
		imp1.makeString("hello", "world");

		StringConcat concat = (s,v) -> System.out.println(s + "," + v);
		concat.makeString("hello", "world");

		StringConcat concat2 = new StringConcat() {

			@Override
			public void makeString(String s1, String s2) {
				System.out.println(s1 + "," + s2);
			}
		};

		concat2.makeString("hello", "world");
	}
}

우리가 람다식으로 구현하지만, 내부에는 익명 객체가 생성이 됩니다.
즉 익병 내부클래스가 내부적으로 람다식에서 사용됩니다.
(위의 코드에서 concat2)

4. 함수를 변수처럼 사용하는 람다식

프로그램에서 변수는

  • 자료형에 기반하여 선언 ex)int a;
  • 매개변수로 전달 ex) int add(int x, int y);
  • 메서드의 반환값으로 사용 ex) return num;

입니다.

람다식은 프로그램 내에서 변수처럼 사용이 가능합니다.
위의 예시처럼 함수의 구현부분이 변수에 대입됩니다.

다른 예시를 보겠습니다.

interface PrintString{
	void showString(String str);
}

public class TestLamda {

	public static void main(String[] args) {

		PrintString lambdaStr = s -> System.out.println(s);
		lambdaStr.showString("Test");

		showMyString(lambdaStr);

		PrintString test = returnString();
		test.showString("Test3");
	}

	public static void showMyString(PrintString p) {
		p.showString("Test2");
	}

	public static PrintString returnString() {
		return s->System.out.println(s + "!!!");
	}
	//함수의 구현부가 마치 변수처럼 반환돼서 변수값에 대입.
}

태그:

카테고리:

업데이트:

댓글남기기