자바에서 람다는 기존의 인터페이스형태의 클래스를 화살표모양의 함수 형태로 표기하는 방법 입니다.
이러한 람다식의 장점은 아래와 같습니다.
1. 코드의 간결성 - 람다를 사용하면 불필요한 반복문의 삭제가 가능하며 복잡한 식을 단순하게 표현할 수 있습니다.
2. 지연연산 수행 - 람다는 지연연상을 수행 함으로써 불필요한 연산을 최소화 할 수 있습니다.
3. 병렬처리 가능 - 멀티쓰레디를 활용하여 병렬처리를 사용 할 수 있습니다.
일반적으로 표기하는 람다식 샘플 입니다.
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class LambdaTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream().map( arg -> arg*2).forEach(System.out::println);
}
}
스트림(stream) 객체에서 map 메소드를 실행 하였습니다.
map은 스트림 객체의 값을 변화시킬 때 사용하는 메소드 입니다.
이와같은 람다식을 쓰지 않고 자바7 이하의 버전으로 표기하려면 아래처럼 해야 합니다.
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class LambdaTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream().map( arg -> arg*2).forEach(System.out::println);
//자바7 이하로 표기
list.stream().map( new Function<Integer, Integer>() { //map람다를 풀어썼습니다.
@Override
public Integer apply(Integer t) {
return t * 2;
}
}).forEach(new Consumer<Integer>() { //foreach에서의 이중콜른 표기법을 풀어 썼습니다.
@Override
public void accept(Integer t) {
System.out.println(t);
}
});
}
}
코드가 딸랑 2줄인 내용이 위 샘플코드처럼 방대해진 것을 볼 수 있습니다.
이러한 람다식은 화살표 모양으로도 사용할 수 있으면서, 메소드 형태로 분리하여 대입하는 방법으로도 사용 할 수 있습니다.
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class LambdaTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream().map( testMethod(aaa->aaa)).forEach(System.out::println);
}
public static Function<Integer,Integer> testMethod(Function<Integer, Integer> fun){
return arg ->{
return fun.apply(arg) * 2; //위 map 객체의 람다식을 메소드로 추가 정의하여 반환합니다.
};
}
}
map객체에서의 람다식을 testMethod 라는 메소드에서 받아서 다시 람다식으로 리턴하는 모습 입니다.
Function으로 반환한 이유는, map객체에서의 인자값은 Function으로 되어 있습니다.
그런데 이러한 메소드로 람다식을 다시 정의하는 방법은 조금 주의해야되는 점이 있습니다.
위 메소드를 간단하게 고쳐보겠습니다.
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class LambdaTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream().map( testMethod(aaa->aaa)).forEach(System.out::println);
}
public static Function<Integer,Integer> testMethod(Function<Integer, Integer> fun){
int number[] = {2};
return arg ->{
return fun.apply(arg) * number[0]++;
};
}
}
위 코드를 실행하면 몇몇 사람들이 "2, 4, 6, 8, 10" 이 출력될꺼야 라고 생각합니다.
왜냐하면 testMethod 메소드가 map 메소드에서 호출 될 때 마다 실행되는 것이라고 생각하기 때문에 number배열의 값은 항상 2로 초기화되어 존재할 것이라 생각 할 수 있기 때문 입니다.
그런데 이를 실행하면 아래와 같은 모습이 나옵니다.
무슨 상황인지 파악하기 위해서 간단한 출력코드를 입력 해 봅니다.
testMethod는 계속되서 사용되지 않았습니다.
testMethod에서 리턴한 함수식만 리스트의 크기에 맞게 map 메소드에 의해서 사용되는 것을 볼 수 있습니다.
이처럼 람다식을 사용할 때 메소드에 의해서 다시 함수로 리턴하는 방법은 메소드 영역의 변수들이 마치 공유 되듯 사용되는 것을 볼 수 있습니다.
이를 응용하면 아래 포스팅처럼 List형태의 값에서 데이터 중복제거하는 방법을 적용 할 수 있습니다.
https://lts0606.tistory.com/180
JAVA List 중복제거, distinct (stream과 Function을 활용)
자바 1.8을 활용한 데이터 중복제거 방법 입니다. List가 포함하는 데이터는 HashMap으로 하였습니다. 물론, 사용자가 만든 vo 객체를 사용해도 무방하며, 일반 String, Integer, float, char 등 다른 자료형
lts0606.tistory.com
공부 할수록, 알면 알 수록 어렵고 재밌는 람다!
좀더 햇갈리지 않도록 열심히 노력해야겠습니다.
'Java(자바) > Java 기본' 카테고리의 다른 글
Java List Map 객체 정렬하기 (0) | 2022.09.05 |
---|---|
Mybatis jdbctype(마이바티스 Jdbctype) (0) | 2022.07.18 |
자바 참조 데이터(Java Array, Java List) 사용간 유의 사항 (0) | 2022.03.21 |
자바로 살펴본 재귀 함수의 동작 방법 - 2 (Java Recursive method with 순열) (2) | 2021.07.28 |
자바로 살펴본 재귀 함수의 동작 방법 - 1 (Java Recursive method) (2) | 2021.07.27 |
댓글