이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

22
람람람 - 함함함 함함함함함함 함함함 함함 8 함함 함함함함 함함함함함 함함 함함함 함함 함함함 함 . - 함함 함함함 함함함함 함함 함함함 함함 함함 함함함함함 함함 함함 함함함 함함함 . - 함함 함함함 함함 함함함함함 , 함함함함 함함함 함함함함함함 함함함함 함함함 함함함 함함 함함함 함 함함 . Runnable runnable = new Runnable() { public void run() { ... } }; Runnable runnable = () -> { ... }; - Runnable 함함함함함함 함함함함 함함 함함 .

Transcript of 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

Page 1: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

- 함수적 프로그래밍을 위해서 자바 8 부터 람다식을 지원하면서 코드 패턴이 많이 바뀌게 됨 .- 익명 함수를 생성하기 위한 식으로 객체 지향 언어보다는 함수 지향 언어에 가깝다 .- 자바 코드가 매우 간결해지고 , 컬렉션의 요소를 필터링하거나 매핑해서 원하는 결과를 쉽게 집계할 수 있다 .

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

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

- Runnable 인터페이스의 익명구현 객체 생성 .

Page 2: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

기본 문법

( 타입 매개변수 , ...) -> { 실행문 ; ... }

(int a) -> { System.out.println(a); }

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

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

람다식에서는 매개 변수의 타입을 일반적으로 언급하지 않으므로 다음처럼 .( 매개 변수 타입은 런타임 시에 대입되는 값에 따라 자동으로 인식 )

하나의 매개변수만 있으면 괄호 생략 가능 .

Page 3: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

기본 문법

() -> { 실행문 ; ... }

(x, y) -> { return x+y ;}

(x, y) -> x+y

중괄호 안에 return 문만 있을 경우 다음과 같이 씀 .

Page 4: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

타겟 타입

- 람다식은 메소드를 가지고 있는 객체를 생성 .

인터페이스 변수 = 람다식 ;- 람다식은 인터페이스 변수에 대입된다 .- 람다식은 인터페이스의 익명 구현 객체를 생성한다 .- 람다식은 대입될 인터페이스의 종류에 따라 작성 방법이 다르다 .- 람다식이 대입될 인터페이스를 람다식의 타겟 타입 .

Page 5: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

함수적 인터페이스

@FunctionalInterfacepublic interface MyFunctionalInterface {    public void method();    public void otherMethod(); //  컴파일 오류}

- 의미 : 하나의 추상 메소드가 선언된 인터페이스만이 람다식의 타켓 타입이 될 수 있는데 이러한 인터페이스 .- 함수적 인터페이스를 작성할 때 두 개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 체킹해주는 기능 (@FunctionalInterface 어노테이션 )

Page 6: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

매개 변수와 리턴값이 없는 람다식 ( 함수적 인터페이스 )

public class MyFunctionalInterfaceExam { 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 call3"); fi.method(); }}

Page 7: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

매개 변수가 있는 람다식 ( 함수적 인터페이스 )

public class MyFunctionalInterfaceExam2 { public static void main(String[] args) { MyFunctionalInterface2 fi; // 두 람다식이 같은 의미 fi = (x) -> { int result = x * 5; System.out.println(result); }; fi.method(2); //----------------------------------------------------- fi = x -> System.out.println(x * 5); fi.method(2); }}

Page 8: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

리턴값이 있는 람다식 ( 함수적 인터페이스 )public class MyFunctionalInterfaceExam3 { public static void main(String[] args) { MyFunctionalInterface3 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)); } public static int sum(int x, int y) { return x + y; }}

Page 9: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

클래스 멤버와 로컬 변수 사용

- 람다식 실행 블록에는 클래스의 멤버 ( 필드와 메소드 ) 및 로컬 변수를 사용할 수 있다 .클래스 멤버의 사용

- 람다식 실행 블록에는 클래스의 멤버인 필드와 메소드를 제약 사항 없이 사용가능 .- 하지만 this 키워드를 사용할 때에는 주의 .- 일반적으로 익명 객체 내부에서 this 는 익명 객체의 참조이지만 , 람다식에서 this 는 내부적으로 생성되는 익명 객체의 참조가 아니라 람다식을 실행한 객체의 참조 .

Page 10: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

클래스 멤버의 사용public class UsingThis { public int outterField = 10; class Inner { int innerField = 20; void method() { MyFunctionalInterface4 fi = () -> { System.out.println("Outter Field: " + outterField); System.out.println("Outter Field: " + UsingThis.this.outterField + "\n"); System.out.println("Inner Field: " + innerField); System.out.println("Inner Field: " + this.innerField + "\n"); }; fi.method(); } }}public class UsingThisExam { public static void main(String[] args) { UsingThis usingThis = new UsingThis(); UsingThis.Inner inner = usingThis.new Inner(); inner.method(); }}

중첩 객체 Inner 에서 람다식을 실행했기 때문에 람다식 내부에서의 this 는 중첩 객체 Inner 입니다 .

Page 11: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

로컬 변수 사용

- 람다식은 메소드 내부에서 주로 작성되기 때문에 로컬 익명 구현 객체를 생성시킨다고 봐야 합니다 .- 람다식에서 바깥 클래스의 필드나 메소드는 제한 없이 사용할 수 있으나 , 메소드의 매개 변수 또는 로컬 변수를 사용하면 이 두 변수는 final 특성을 가져야 합니다 .- 따라서 매개 변수 또는 로컬 변수를 람다식에서 읽는 것은 허용되지만 , 람다식 내부 또는 외부에서 변경할 수 없습니다 .

public class UsingLocalVariable { void method(int arg) { int localVar = 40; // arg = 31; // final 특성 때문에 수정 불가 // localVar = 41; // final 특성 때문에 수정 불가 MyFunctionalInterface5 fi = () -> { System.out.println("arg: " + arg); System.out.println("localVar: " + localVar); }; fi.method(); }}

Page 12: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

표준 API 의 함수적 인터페이스

- 자바 8 부터는 빈번하게 사용되는 함수적 인터페이스 (Functional Interface) 는 java.util.function 표준 API 패키지로 제공합니다 . - 목적 : 함수적 인터페이스를 메소드 또는 생성자의 매개 타입으로 사용하여 람다식을 대입할 수 있도록 하기 위해서 입니다 . - java.util.function 패키지의 함수적 인터페이스는 크게 Con-sumer, Supplier, Function, Operator, Predicate 로 구분됩니다 .

Page 13: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

Consumer 함수적 인터페이스

Page 14: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

Supplier 함수적 인터페이스

Page 15: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

Function 함수적 인터페이스

Page 16: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

Operator 함수적 인터페이스

Page 17: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

Predicate 함수적 인터페이스

Page 18: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

andThen() 과 compose() 디폴트 메소드

- Comsumer, Function, Operator 종류의 함수적 인터페이스는 andThen() 과 compose() 디폴트 메소드를 가지고 있습니다 . - andThen() 과 compose() 메소드는 두 개의 함수적 인터페이스를 순차적으로 연결하고 , 첫 번째 처리 결과를 두 번째 매개값으로 제공해서 최종 결과값을 얻을 때 사용합니다 .- andThen() 과 compose() 의 차이점은 어떤 함수적 인터페이스부터 먼저 처리하느냐에 따라 다릅니다 .

Page 19: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

andThen() 과 compose() 디폴트 메소드

- Consumer 의 순차적 연결- Function 의 순차적 연결

Page 20: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

and(), or(), negate() 디폴트 메소드와 isEqual() 정적 메소드- 이 메소드들은 각각 논리 연산자인 &&, ||, ! 과 대응된다 .

 minBy(), maxBy() 정적 메소드

- 이 두 메소드는 매개값으로 제공되는 Comparator 를 이용해서 최대 T 와 최소 T 를 얻는 BinaryOperator<T> 를 리턴합니다 .

Page 21: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

메소드 참조

- 메소드 참조 (Method Reference) 는 말 그대로 메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어 , 람다식에서 불필요한 매개 변수를 제거하는 것이 목적입니다 .

정적 메소드와 인스턴스 메소드 참조

클래스 :: 메소드 ;

매개 변수의 메소드 참조

람다식에서 제공되는 a 매개 변수의 메소드를 호출해서 b 매개 변수를 매개값으로 사용하는 경우

(a, b) -> { a.instanceMethod(b); }Class :: instanceMethod

Page 22: 이것이 자바다 Chap.14 람다식 Lambda expression(java)(KOR)

람다식

생성자 참조

- 생성자를 참조한다는 것은 객체 생성을 의미

(a, b) -> { return new Class(a, b); }Class :: new;