Link Search Menu Expand Document

Java Lamda Experssions

Table of contents

  1. Lamda Experssions
    1. what is Lambda?
    2. Target Funtion
    3. Functional Interface
    4. History of Lambda
    5. Why Use Lambda?
    6. Syntax of Lambda
    7. Lambda with Arguments
    8. Lambda Return
    9. Target Funtion
    10. Functional Interface
    11. Class Member with Local Variables

Lamda Experssions

what is Lambda?

익명함수를 생성하기 위한 식

▸ 자바는 람다식을 함수적 인터페이스의 익명 구현 객체로 취급

▸ 람다식의 형태는 매개변수를 가진 코드블럭이지만 런타임시에는 익명구현객체를 생성

▸ 어떤 인터페이스를 구현할지는 대입되는 인터페이스에 달려있음

▸ 객체지향언어보다 함수지향언어에 가까움

Target Funtion

▸ 람다식형태는 매개변수를 가진 코드블럭이기 때문에 자바의 메서드를 선언하는 것처럼 보여지지만 자바에서는 메서드를 단독으로 선언할 수 없고 항상 클래스의 멤버로 선언하기 때문에 람다식은 단순히 메서드를 선선하는게 아니라 객체를 생성하는 것

▸ 람다식은 인터페이스 변수에 대입됨 즉, “인터페이스의 익명구현객체를 생성”

▸ 인터페이스는 직접 객체화 할 수 없기 때문에 구현 클래스가 필요한데 람다식은 클래스 선언 없이 익명구현객체를 직접 생성하고 객체화 함

람다식은 대입될 인터페이스의 종류에 따라 달라지기 때문에 람다식이 대입될 인터페이스를 람다식의 타겟타입(Target Type)이라고 함

Functional Interface

함수적 인터페이스, @FunctionalInterface

▸ 모든 인터페이스를 람다식의 타겟타입으로 사용할 수는 없음

▸ 람다식이 하나의 메서드를 정의하기 때문에 두 개 이상의 추상메서드가 선언된 인터페이스는 람다식을 이용할 수 없음

▸ 하나의 추상메서드가 선언된 인터페이스만이 람다식의 타겟타입이 될 수 있는데 이러한 인터페이스를 함수적 인터페이스라고 함

▸ 함수적 인터페이스를 작성할 때 2개 이상의 추상메서드가 선언되지 않도록 컴파일러가 확인할 수 있도록 인터페이스 선언시에 @FunctionalInterface 애너테이션을 선언

History of Lambda

람다식은 수학자 알론조 처치(Alonzo Church)가 발표한 계산법

제자 존 메카시(John McCharthy)가 프로그래밍 언어에 도입

→ 람다 계산법에서 사용된 식을 프로그래밍 언어에 접목하게 된것

Why Use Lambda?

  1. 코드가 간결해짐

  2. 컬렉션요소(대용량 데이터)를 필터링 또는 매핑해 쉽게 집계함

Syntax of Lambda

▸ 하나의 매개변수만 있을 경우에는 괄호() 생략가능

▸ 하나의 실행문만 있다면 중괄호 {} 생략가능

▸ 매개변수가 없다면 괄호 생략 불가

syntax

(매개변수 … ) -> { … 실행문 … }

실행문이 한 문장일경우 실행문의 {}를 생략해도 됨

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

	//추상메서드는 구현객체에서 반드시 정의해야함
	MyFuncInter fi = new MyFuncInter() {	
		@Override
		public void method() { System.out.println("추상메서드 구현 - 익명구현객체"); }
	};
	fi.method(); //추상메서드 구현 - 익명구현객체
	
	//람다식
	fi = () -> { System.out.println("추상메서드 구현 - 람다식(1)");	};
	fi.method(); //추상메서드 구현 - 람다식(1)	
	
	fi = () -> System.out.println("추상메서드 구현 - 람다식(2)");
	fi.method(); //추상메서드 구현 - 람다식(2)
	
}
}

//메소드를 하나만 가짐
@FunctionalInterface
interface MyFuncInter{
	void method();
}

Lambda with Arguments

▸ 람다식에서는 런타임시에 대입되는 값에 따라 자동으로 인식될 수 있기 때문에 람다식에서는 매개변수의 타입을 일반적으로 언급하지는 않음

예제

public class FunctionalInterfaceMain {
public static void main(String[] args) {
	
	MyFuncInter fi;
	
	fi = (int x) -> {
		int result = (x * 5);
		System.out.println(x + " * 5 = " + result);
	};
	fi.method(5);   //25
	
	fi = (x) -> System.out.println(x + " * 5 = " + x*5 );
	fi.method(10);  //50
	
	fi = x -> System.out.println(x + " * 10 = " + x*10 );
	fi.method(10);  
	
}
}

@FunctionalInterface
interface MyFuncInter{
	void method(int x);
}

Lambda Return

void가 아닌 리턴값이 있는 interface 가상메소드를 사용한다면 Lambda에 리턴값이 있어야함

실행문이 리턴문 하나밖에 없으면 리턴 키워드도 생략할 수 있음

예제

public class FunctionalInterfaceMain {
public static void main(String[] args) {
	
	MyFuncInter fi;
	
	fi = (x , y) -> {
		int result = x + y;
		return result; // 리턴값 반환
	};
	
	int result = fi.method(10, 20);
	System.out.println(result);
	System.out.println(fi.method(10, 20));
	
	fi = (x,y) -> { return x+y;	};	
	System.out.println(fi.method(10, 200));
	
	//실행문이 리턴문 하나밖에 없으면 리턴 키워드도 생략할 수 있음
	fi = (x,y) -> x/y; 
	System.out.println(fi.method(10, 3));

	fi = (x,y) -> divide(10, 5);
	System.out.println(fi);
	
}

private static int divide(int x, int y) {
	return x/y;
}

}

@FunctionalInterface
interface MyFuncInter {
	int method (int x, int y);
}

Target Funtion

▸ 람다식형태는 매개변수를 가진 코드블럭이기 때문에 자바의 메서드를 선언하는 것처럼 보여지지만 자바에서는 메서드를 단독으로 선언할 수 없고 항상 클래스의 멤버로 선언하기 때문에 람다식은 단순히 메서드를 선선하는게 아니라 객체를 생성하는 것

▸ 람다식은 인터페이스 변수에 대입됨 즉, “인터페이스의 익명구현객체를 생성”

▸ 인터페이스는 직접 객체화 할 수 없기 때문에 구현 클래스가 필요한데 람다식은 클래스 선언 없이 익명구현객체를 직접 생성하고 객체화 함

람다식은 대입될 인터페이스의 종류에 따라 달라지기 때문에 람다식이 대입될 인터페이스를 람다식의 타겟타입(Target Type)이라고 함

Functional Interface

함수적 인터페이스, @FunctionalInterface

▸ 모든 인터페이스를 람다식의 타겟타입으로 사용할 수는 없음

▸ 람다식이 하나의 메서드를 정의하기 때문에 두 개 이상의 추상메서드가 선언된 인터페이스는 람다식을 이용할 수 없음

▸ 하나의 추상메서드가 선언된 인터페이스만이 람다식의 타겟타입이 될 수 있는데 이러한 인터페이스를 함수적 인터페이스라고 함

▸ 함수적 인터페이스를 작성할 때 2개 이상의 추상메서드가 선언되지 않도록 컴파일러가 확인할 수 있도록 인터페이스 선언시에 @FunctionalInterface 애너테이션을 선언

Class Member with Local Variables

람다식의 실행블럭에는 클래스 멤버 (필드, 메서드) 및 로컬 변수를 사용할 수 있음

▸ 클래스 멤버는 제약없이 사용할 수 있지만 로컬변수는 제약이 있음

▸ 클래스 멤버를 사용할 때 this 키워드를 사용할 때는 일반적으로 익명객체 내부에서 this는 익명객체를 참조하지만 람다식에서 this는 내부적으로 생성되는 익명객체가 아니라 람다식을 실행한 객체를 의미

UsingThis

public class UsingThis {

	public int outterField = 10;
	
    //내부클래스의 가상메소드를 람다식으로 선언
	public class Inner {
		int innerField = 20;
		
		void method() {			
			MyFuncInter fi;
			fi = () -> { 
				System.out.println("outterField = " + outterField); //10
				System.out.println("outterField = " + UsingThis.this.outterField); //10
				System.out.println("innerField = " + innerField); //20
				System.out.println("innerField = " + this.innerField); //20
			};
			fi.method();
		}
	}

}

@FunctionalInterface
interface MyFuncInter {
	void method();
}

UsingThisMain : 실행부

public class UsingThisMain {
public static void main(String[] args) {
	
    //객체 생성 후 
	UsingThis usingThis = new UsingThis();
    //그 객체의 내부 클래스 객체를 만든 후
	UsingThis.Inner inner = usingThis.new Inner();
	//내부클래스 객체의 함수실행
    inner.method();
}
}

이 웹사이트는 jekyll로 제작되었습니다. Patrick Marsceill, Distributed by an MIT license.