2019. 7. 30. 23:08ㆍIT/Java
1절 람다식이란?
함수적 프로그래밍
- y = f(x) 형태로 함수의 구성된 프로그래밍 기법
- 데이터를 매개값으로 전달하고 결과를 받는 코드들로 구성
- 대용량 데이터의 처리시에 유리
- 병렬 처리와 이벤트 지향 프로그래밍에 적합
- 현대적 프로그래밍 기법 ( 객체지향 + 함수적 프로그래밍 )
람다식을 수용한 이유
- 코드가 매우 간결
- 컬렉션 요소(대용량 데이터)를 필터링 또는 매핑해서 쉽게 집계할 수 있다.
자바는 람다식을 함수적 인터페이스의 익명 구현 객체로 취급
🔹 람다식 -> 매개변수를 가진 코드 블록 -> 익명 구현 객체
Runnable runnable = () -> {...}; //람다식
⬇️
Runnable runnable = new Runnable() {
public void run() {...} //익명 구현 객체
};
2절 람다식 기본 문법
함수적 스타일의 람다식을 작성하는 방법
(타입 매개변수, ...) -> { 실행문;...}
-
매개타입은 런타임시에 대입값에 자동으로 인식하기 때문에 생략 가능
(a) -> {System.out.println(a);}
-
하나의 매개변수만 있을경우에는 괄호() 생략 가능
-
하나의 실행문만 있다면 중괄호 { } 생략가능
-
매개변수가 없다면 괄호 ( ) 생략할 수 없음
a -> { System.out.println(a); } a -> System.out.println(a) () -> { 실행문;...}
-
리턴값이 있는 경우, return 문을 사용
-
중괄호 { } 에 return문만 있을 경우, 중괄호 생략 가능
(x,y) -> { return x+y; }; (x,y) -> x + y
3절 타겟 타입과 함수적 인터페이스
람다식의 형태는 매개 변수를 가진 코드 블록이기 때문에 자바의 메소드를 선언하는 것처럼 보입니다. 하지만 자바는 메소드를 가지고 있는 객체를 생성해 낸다!
인터페이스 변수 = 람다식;
타겟 타입(target type)
- 람다식이 대입될 인터페이스
- 익명구현 객체를 만들 때 사용하는 인터페이스이다.
함수적 인터페이스 (functional interface)
-
하나의 추상 메소드가 선언된 인터페이스
-
@Functionalnterface 어노테이션
함수적 인터페이스를 작성할 때 두 개이상의 추상 메소드가 선언되지 않도록 컴파일러가 채킹.
매개변수와 리턴값이 없는 람다식
@FunctionalInterface
public interface MyFunctionalInterface {
public void method();
}
MyFunctionalInterface fi = () -> {...};
//method()에 매개변수가 없기 때문에 ()로 표시
fi.method(); //{..} 실행
4절 클래스 멤버와 로컬 변수 사용
클래스의 멤버 사용
-
람다식 실행 블록에는 클래스의 멤버인 필드와 메소드를 제약 없이 사용할 수 있다.
-
람다식 실행 블록내에서 this는 람다식을 실행한 객체의 참조이다.
public class UsingThis { public int field = 10; class Inner { int field = 30; void method() { MyFunctionalInterface fi; fi = () -> { System.out.println("outterField: " + UsingThis.this.field ); System.out.println("innerField: " + this.field ); }; fi.method(); } } }
로컬 변수의 사용
-
람다식은 함수적 인터페이스의 익명 구현 객체를 생성한다.
-
람다식에서 사용하는 외부 로컬 변수는 final 특성을 갖는다.
-> 익명 객체의 로컬 변수 사용 공부
매개변수 또는 로컬변수를 람다식 내에서 읽기는 가능하나 내부 또는 또는 외부에서 변경할 수 없다.
public class UsingLocalVariable { void method(int arg) { int localVar = 40; //arg= 30; -> final 특성 때문에 수정 불가 //localVar = 50; -> fianl 특성 때문에 수정 불가 MyFunctionalInterface fi = () -> { System.out.println("arg:" + arg ); System.out.println("localVal: " + localVar); }; fi.method(); }
5절 표준 API로 제공되는 함수적 인터페이스
Consumer 함수적 인터페이스
⭐️ 특징 : 리턴값이 없는 accept() 메소드를 가지고 있다.
-
Consumer
Consumer<String> consumer = t -> {t를 소비하는 실행문;};
➡️ String 타입 파라미터이니 매개값 t 는 String 타입
-
BiConsumer<T, U>
BiConsumer<String, String> consumer = (t, u) -> {t,u를 소비하는 실행문;}
➡️ <String, String> 이므로 매개값 t와 u도 모두 String
-
DoubleConsumer
DoubleConsumer consumer = d -> {d를 소비하는 실행문;}
➡️ Double! d는 double 타입(고정)
-
ObjIntConsumer
ObjIntConsumer<String> consumer = (t, i) -> {t와 i를 소비하는 실행문;}
➡️ String 이므로 매개값 t는 String 타입, 매개값 i는 int타입(고정)
Supplier 함수적 인터페이스
⭐️ 특징 : 매개 변수가 없고 리턴값이 있는 getXXX()메소드를 가지고 있다.
-
Supplier
Supplier<String> supplier = () -> {...; return "문자열";}
➡️ < String > 이므로 return은 String 타입
-
IntSupplier
IntSupplieer supplier = () ->{...; return int값;}
➡️ return값은 반드시 int타입
Function 함수적 인터페이스
⭐️ 특징 : 매개 변수와 리턴값이 있는 applyXXX()메소드를 가지고 있다.
⭐️ 이들 메소드는 매개값을 리턴값으로 매핑(타입변환)하는 역할을 한다.
-
Function<T, R>
Function<Student, String> function = t -> {return t.getName;}
➡️ t : Student 타입/ 리턴값 : String 타입 Student 객체를 String으로 매핑
-
ToIntFunction
ToIntFunction<Student> function = t ->{return t.getScore();} ToIntFunction<Student> function = t -> t.getScore();
➡️< Student >이므로 t -> Student 타입 /리턴값 -> int 타입(고정) Student 객체를 int로 매핑.
Operator 함수적 인터페이스
⭐️ 특징 : 매개 변수와 리턴값이 있는 applyXXX()메소드를 가지고 있다.
Function의 역할 매핑(타입변환) 이라면 Operator는 "연산을 수행한 후" 동일한 타입으로 리턴값 제공!
-
IntBinaryOperator
IntBinaryOperator operator = (a,b) -> {...; return int값;}
➡️ a,b 모두 int 타입 연산 후 리턴값도 int 타입
-
IntUnaryOperator
IntUnaryOperator operator = a -> {...; return int값;}
➡️ a int 타입. 연산 후 리턴값도 int 타입
Predicate 함수적 인터페이스
⭐️ 특징 : 매개 변수와 boolean 리턴값이 있는 testXXX()메소드를 가지고 있다.
testXX()메소드는 매개값 조사해서 true 또는false 를 리턴하는 역할
-
Predicate
Predicate<Student> predicate = t -> {return t.getSex().equals("남자");} Predicate<Student> predicate = t -> t.getSex().equals("남자");
➡️ < Student >이므로 매개값 t : Student 타입 / return 값 : boolean 타입(고정)