jnk1m
Foliage IT
jnk1m
전체 방문자
오늘
어제
  • 분류 전체보기 (209)
    • Today I Learned (34)
    • Java (47)
    • Database (15)
    • [NHN Academy] (27)
    • Spring (47)
    • HTML + CSS + JavaScript (11)
    • JSP (3)
    • Node.js (10)
    • React Native (2)
    • 기타 (8)
    • 스크랩 (5)

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
글쓰기 / 관리자
jnk1m

Foliage IT

JAVA 자바 웹 개발 Day14 (Note): 람다식
Java

JAVA 자바 웹 개발 Day14 (Note): 람다식

2022. 2. 24. 22:31

2022/2/24

 

요즘 다시 각광을 받고 있는 함수 식 프로그래밍. 객체 지향과 함수 식을 혼합해서 사용해보자. 자바는 함수 식 프로그래밍을 위해서 람다식을 지원하고 있다. 기존의 코드 패턴이 달라짐.

 

람다식

: 익명 함수를 생성하기 위한 식으로 객체 지향 언어보다 함수 지향 언어에 가깝다.
예) Runnable 인터페이스의 익명 구현 객체를 생성하는 코드.


람다식은 (매개변수)->{실행코드} 형태로 작성되는데, 마치 함수 정의 형태를 띠고 있지만 프로그램이 돌아가고 있을 때 인터페이스의 익명 구현 객체로 생성된다. 실행될 때 생성이 된다… 어떤 인터페이스를 구현할 것인가는 대입되는 인터페이스에 달려있다. 위에 코드에서는 런어블로 구현이 되니까 런 메서드로 구현이 되는 것. 앞에 선언하는 변수가 중요하다. 변수의 타입에 맞게끔 객체가 자동으로 생성된다. (처음 시작하는 입장에서 람다는 몰라도 됨 편하게 듣자)

람다식 기본 문법

함수적 스타일의 람다식을 작성하는 방법
(타입 매개변수, …) -> {실행문}

//매개변수를 받아서 오른편에 있는 실행문을 실행하겠다. 화살표가 있으면 람다다……


ex) int형 매개변수 a의 값을 출력하는 람다식
(int a) -> {System.out.println(a);}
매개변수 타입은 런타임 시에 대입되는 값에 따라 자동으로 인식될 수 있기 때문에 람다식에서는 매개변수의 타입을 일반적으로 언급하지 않는다.
(a) -> {System.out.println(a);}
매개변수가 하나만 있다면 () 소괄호 생략할 수 있고, {} 안에 실행문이 하나면 중괄호도 생략할 수 있다.
a -> System.out.println(a)
만약 매개변수가 없다면, 람다식에서 매개변수 자리가 없어지므로 빈 괄호()를 반드시 표기해줘야 한다.
()->{…}
중괄호 {} 실행하고, 결괏값을 리턴해야 한다면 return 문으로 결괏값을 지정할 수 있다.
(x, y) -> {return x * y;}
중괄호 {} 안에 return문만 있을 경우, 람다식에서는 return문을 사용하지 않고 바로 식만 작성 가능.
(x,y) -> x*y

 

타겟 타입과 함수적 인터페이스
람다식의 형태는 매개변수를 가진 코드 블록이기 때문에 메서드를 선언하는 거처럼 보임. 자바는 메서드를 단독으로 선언할 수 없고 항상 클래스의 안에 있기 때문에 람다는 메서드를 가지고 있는 객체를 생성해줌.


인터페이스 변수명 = 람다식;
이 말인즉, 람다가 인터페이스에 익명 구현 객체를 생성한다는 소리.
대입된 인터페이스에 따라 작성 방법이 달라짐. 람다식이 대입되는 인터페이스가 람다식의 타깃 타입이라고 한다.

 

1.  함수적 인터페이스 @FunctionalInterface
모든 인터페이스를 람다식의 타깃 타입으로 사용할 수는 없다.
람다식이 하나의 메서드를 정의하기 때문에 두 개 이상의 추상 메서드가 선언된 인터페이스는 람다식을 이용해 구현 객체를 생성할 수 없다. 함수적인터페이스 = 한 개의 추상 메서드가 있어 람다식으로 만들 수 있는 인터페이스

 

2.  매개변수와 리턴 값이 없는 람다식
이클립스에 만들어놓은 인터페이스를 타깃 타입으로 갖는 람다식 (런타임 시 객체 생성됨)
Myfuctionalinterface my = () -> {……};
사용할 때는 변수명.메서드명()으로 사용
my.method();

 

3.  매개변수가 있는 람다식
Myfuctionalinterface my = (변수 명) -> {……};
my.method(값);

 

4.  리턴 값이 있는 람다식
매개변수도 있고 리턴 값도 있는 추상 메서드를 가진 인터페이스가 있다면……
Myfuctionalinterface my = (변수 명) -> {…return 값;…};
Myfuctionalinterface my = (변수 명) -> 값;

Myfuctionalinterface my = (변수 명) -> {return 매서드(값);};
Myfuctionalinterface my = (변수 명) -> 매서드(값); //생략버전
타입 변수 = my.method(값)

 

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

람다식이 실행 블록에는 클래스의 멤버(변수, 메서드) 및 지역변수를 사용할 수 있다. 클래스의 멤버는 제약 사항이 없이 사용 가능하지만, 지역 변수는 제약사항이 따른다.

 

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

 

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

 

표준 API의 함수적 인터페이스
자바 8부터는 자주 사용되는 함수적 인터페이스를 java.util.function 패키지로 제공.
메서드의 매개변수, 생성자의 매개변수로 주로 사용되어 매개변수에 람다로 대입 가능하게 하기 위해 주로 사용


[ 크게 5가지로 분류 ]

       Consumer    

       Supplier

       Function

       Operator

       Predicate

 

1.   Consumer 함수적 인터페이스
accept()
Consumer <T>         void accept(T t)
BiConsumer <T, U>   
DoubleConsumer / IntConsumer / LongConsumer : 기본형 받아 소비
ObjDoubleConsumer / ObjIntConsumer / ObjLongConsumer : 객체와 기본형 받아 소비

 

2.   Supplier
매개변수 x, 리턴해주는 getXXX() 메서드
Supplier <T>         T get()
BooleanSupplier            boolean      getAsBoolean()
DoubleSupplier             double getAsDouble()
IntSupplier
LongSupplier       

 

3.   Function
매개 값, 리턴 값있는 applyXXX() 메서드
Function <T, R> //T타입으로 넣어주면 R 타입으로 리턴.
R apply(T t)
BiFunction <T, U, R>   R apply(T t, U u) 기본형 -> 기본형
기본형 To기본형 Function// 객체 -> 기본형
To기본형 Function

 

4.   Operator
매개변수와 리턴 값이 있는 applyXXX() 메서드
매개변수 받아 연산 후 동일한 타입으로 리턴 값 제공
UnaryOperator <T>    T apply(T t)
BiOperator <T>       T apply(T t, T t)
DoubleBinaryOperator / DoubleUnaryOperator
Int... / Int...
Long.. / Long..

 

5.   Predicate
매개변수와 boolean타입 리턴 값이 있는 testXXX() 메서드
Predicate <T>        boolean test(T t)
BiPredicate <T, U>   boolean test(T t, U u)
DoublePredicate / IntPredicate / LongPredicate

6.   andThen(), compose()
Consumer, Function, Operator 종류의 인터페이스는 andThen(), compose() 디폴트 메서드를 가지고 있다. 두 메서드는, 두 개의 함수적 인터페이스를 순차적으로 연결하고, 첫 번째 처리 결과를 두 번째 매개 값으로 제공해서 최종 결괏값을 얻을 때 사용

#andThen(): A->B
인터페이스 AB =인터페이스 A.andThen(인터페이스 B)
최종 결과 = 인터페이스 AB.method();
에이 먼저 하고 결과를 뒤에 토스

#compose(): B->A
인터페이스 AB =인터페이스 A.andThen(인터페이스 B)
최종 결과 = 인터페이스 AB.method();
B부터 처리를 하고 그 값을 A한테 넣어준다

7.   and(), or(), negate() 디폴트 메서드, isEqual() 정적 메서드
&& || ! 논리 연산자와 대응된다.
and(): 두 개의 Predicate가 모두 true를 리턴하면 최종적으로 true 리턴
or(): 둘 중 하나라도 true면 최종적으로 true 리턴
negate(): true/ flase 반전시켜서 리턴

 

메서드 참조
람다식에서 불필요한 매개변수를 제거하는 것을 목적으로 사용하는 문법
ex) Math.max(10, 20); --> 20 리턴해줌 (큰 수)
(a, b) -> Math.max(a, b);
IntBinaryOperator op = Math::max;

1) 클래스 메서드와 인스턴스 메서드 참조
클래스::메서드
참조 변수::메서드

 

2) 매개변수의 메서드 참조
(a, b) -> { a.instanceMethod(b); };
클래스::instanceMethod

 

3) 생성자 참조
== 객체 생성 의미함.
(a, b) -> { return new 클래스(a, b); }
클래스::new

 

 

--

오늘 진짜 정신 나갔다... 표준 API부터 정신줄을 놔버려서 수업 내용 하나도 못 따라감..

오후 시간대는 그냥 다 날린 거나 마찬가지. 정신 차리자 

    'Java' 카테고리의 다른 글
    • JAVA 자바 웹 개발 Day15 (Note): 스트림, enum
    • JAVA 자바 웹 개발 Day14 (Code)
    • JAVA 자바 웹 개발 Day13 (Code)
    • JAVA 자바 웹 개발 Day13 (Note): 입출력, 파일 클래스, 스트림, 스레드

    티스토리툴바