티스토리 뷰
자바에서 람다는 메서드로 전달할 수 있는 익명 함수라고 할 수 있으며 이름은 없지만 파라미터, 바디, 반환 형식, 예외를 가지며 다음과 같은 특징이 있다.
람다 표현식은 함수형 인터페이스의 인스턴스(함수형 인터페이스를 구현한 클래스의 인스턴스)라 할 수 있다.
함수형 인터페이스는 디폴트 메서드를 제외한 추상 메서드가 오직 하나인 인터페이스이다.
@FunctionalInterface 어노테이션이 붙어 있는 것이 함수형 인터페이스이다.
함수 디스크립터(
람다식(Lambda Expression) 내에서 사용되는 지역 변수는 final이 붙지 않아도 상수로 간주되며, 람다식으로 선언돼 변수명은 다른 변수명과 중복될 수 없다,
1. 람다식 장점
- 익명 클래스처럼 많은 코드를 구현할 필요가 없어 코드가 간결핟,
- 읽기 수운 코드를 작성할 수 있어서 가독성이 좋아진다.
- 함수를 만드는 과정 없이 한 번에 처리할 수 있어 생산성이 높아진다.
- 병렬 프로그래밍이 용이하다.
2. 람다식 단점
- 람다식으로 작성한 코드는 재사용이 어려우며 디버깅이 어렵다.
- 비슷한 코드가 산재될 수 있어서 지저분한 코드를 만들 수 있다.
- 재귀로 만 들 경 우에 부적합하다.
3. 람다식
- 형식 : 람다 파라미터 -> 람다 바디
- 표현식
- (arg1, arg2...) -> { body }- (params) -> expression- (params) -> statement- (params) -> { statements }- (int a, int b) -> { return a + b; };
-> 타입 추론에 의한 타입 제거 : (a, b) -> { return a+b } ;
-> 무엇인가를 반환하거나 한 줄 표현식이 가능하면return 삭제 : (a, b) -> a+b;- () -> System.out.println("Hello ");
-> 파라미터없고 Hello 출력 System.out::println;
() -> System.out.println("Hello "); // 파라미터 없고 Hello 출력
(String s) -> { System.out.println(s); } // String s입력 매개변수로 받아 출력
() -> 8514790 //파라미터 없고 8514790가 리턴
() -> { return 3.14 }; //파라미터없고 3.14 리턴
4 간단한 예제
public static void main(String[] args) {
// 람다 사용
Runnable r1 = () -> System.out.println("Hello 람다 사용 ");
// 익명 클래스 사용
Runnable r2 = new Runnable() {
@Override
public void run() {
System.out.println("Hello 익명 클래스 사용");
}
};
process(r1);
process(r2);
// 직접 전달
process(() -> System.out.println("Hello 직접 전달 "));
}
public static void process(Runnable r) {
r.run();
}
결과 :
- Hello 람다 사용
- Hello 익명 클래스 사용
- Hello 직접 전달
소스 : https://github.com/hyomee/code/blob/main/Java/function/lamda/basic/LamdaBasicMain.java
GitHub - hyomee/code
Contribute to hyomee/code development by creating an account on GitHub.
github.com
5. java.util.function 함수형 인터페이스
5-1. Predicate
/**
* Represents a predicate (boolean-valued function) of one argument.
* This is a functional interface whose functional method is test(Object).
* Since: 1.8 Type
* parameters: <T> – the type of the input to the predicate
*/
@FunctionalInterface
public interface Predicate <T> {
boolean test(T t);
}
test 추상 메서드를 정의하며 하나의 제네릭을 인수로 받아 불리언을 반환한다,
public static <T> List<T> filetr(List<T> ls, Predicate<T> p) {
List<T> resuts = new ArrayList<>();
for ( T e : ls) {
if (p.test(e)) {
resuts.add(e);
}
}
return resuts;
}
Predicate<Car> pCar = (Car car)-> "검정".equals(car.getColor());
List<Car> blackCar = filetr(cars, pCar);
filter 메서드는 Predicate를 인수로 받아서 결과를 boolean으로 돌려주는 함수로 (Car car) -> "검정". equals(car.getColor() 람다를 수행하여 참/거짓을 돌려준다., 참이면 resuts 객체에 추가한다,
소스 : https://github.com/hyomee/code/blob/main/Java/function/lamda/basic/JavaUtilFunctionPredicate.java
GitHub - hyomee/code
Contribute to hyomee/code development by creating an account on GitHub.
github.com
5-2. Consumer
/**
* Represents an operation that accepts a single input argument and returns no result. Unlike most other
* functional interfaces, Consumer is expected to operate via side-effects.
* This is a functional interface whose functional method is accept(Object).
* Since: 1.8
* Type parameters: <T> – the type of the input to the operation
*/
@FunctionalInterface
public interface Consumer <T> {
void accept(T t);
}
accept추상 메서드를 정의하며 하나의 제네릭을 인수로 받아 void를 반환한다. 즉 T형식의 객체를 인수로 받아서 어떤 작업을 하고 싶을 때 사용한다,
public static <T> void forEach(List<T> ls, Consumer<T> c) {
for ( T e : ls) {
c.accept(e);
}
}
Consumer<Car> pCar = (Car car)-> System.out.println(car.toString());
forEach(cars, pCar);
car 객체의 내용을 출력하는 기능으로 Consumer 변수에 작업 기능을 넣고 사용하였다.
소소 : https://github.com/hyomee/code/blob/main/Java/function/lamda/basic/JavaUtilFunctionConsumer.java
GitHub - hyomee/code
Contribute to hyomee/code development by creating an account on GitHub.
github.com
5-3. function
/**
* Represents a function that accepts one argument and produces a result.
* This is a functional interface whose functional method is apply(Object).
* Since: 1.8 Type
* parameters: <T> – the type of the input to the function
* <R> – the type of the result of the function
*/
@FunctionalInterface
public interface Function <T, R> {
R apply(T t);
}
제너릭 형식 T를 인수로 받아서 제너릭 형식 R 객체를 반환하는 추상 메서드 apply를 정의하고 앗다.
public static <T, R> List<String> map(List<T> ls, Function<T, R> c) {
List<String> result = new ArrayList<>();
for ( T e : ls) {
result.add((String) c.apply(e));
}
return result;
}
Function<Car, String> pFunction = (Car car)-> car.getCompany();
List<String> result = map(cars, pFunction);
System.out.println(result.toString());
pFunction 변수는 car를 인수로 전달받아서 car의 회사명을 리턴하는 함수로 정의하고 map 메서드에서 수행하여 객체를 반환한다,
소스 : https://github.com/hyomee/code/blob/main/Java/function/lamda/basic/JavaUtilFunctionConsumer.java
GitHub - hyomee/code
Contribute to hyomee/code development by creating an account on GitHub.
github.com
'프로그램이야기' 카테고리의 다른 글
프로그램 이야기 첫번째 - 어떻게 학습 할까 (0) | 2023.01.11 |
---|---|
6. 람다이야기 2 (0) | 2022.06.14 |
4. 동작파라미터 2 (Behavior Parameterization) (0) | 2022.06.01 |
3. 동작 파라미터 1 - 일급객체 (0) | 2022.06.01 |
3. Java enum (0) | 2022.05.13 |