[ Lambda ]
[ 람다함수 ]
프로그래밍 언어에서 사용되는 개념으로 익명함수를 지칭하며 함수를 단순하게 표현하는 방법.
[ 장점 ]
- 코드의 간결성 : 복작한 식을 단순히 표현 가능.
- 지연연산 수행 : 지연실행 함으로 불필요한 연산을 최소화한다.
- 지연실행이란 프로그램이 실행될 때 메소드가 메모리에 올라가 있는 상태가 아닌 코드에서 필요할때만 실행되는 (Lazy Loading)것을 의미한다
- 병렬처리 가능 : 멀티쓰레드를 활용하여 병렬처리 가능. (Stream 이용)
[ 단점 ]
- 람다식의 호출이 까다롭다.
- 람다 Stream 사용 시 for, while 문보다 비효율적일 수 있다.
- for, while 문은 break를 통해 탈출조건을 만들 수 있지만 stream.forEach()의 경우 조건이 만족됬다할지라도 끝까지 검사를 해야되는 경우가 생김
- 람다식을 너무 많이 사용하게 되면 가독성을 떨어트릴 수 있다.
[ 예제 ]
// 기존 자바 문법
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Welcome Heejin blog");
}
}).start();
// 람다식 사용
new Thread(()->{
System.out.println("Welcome Heejin blog");
}).start();
[ 함수 ]
람다를 함수형 인터페이스로 사용될 수 있는데, Interface의 메소드를 정의하고 메인 함수에서 구현하는 방식으로 사용할 수 있다.
@FunctionalInterface
interface Math {
public int Calc(int first, int second);
}
public static void main(String[] args){
Math plusLambda = (first, second) -> first + second;
System.out.println(plusLambda.Calc(4, 2));
}
[ Stream ]
- 데이터를 변경하지 않는다. ( 읽기만 가능 )
- 일회성이다. ( 다시 사용하려면 스트림을 다시 생성해야 함 )
- 지연 연산을 수행한다.
- 병렬 실행 가능
// 리스트 컬렉션
List<Integer> list = Array.asList(0,1,2);
Stream<Integer> intStream = list.stream();
// 배열로 생성
Stream<String> stringStream = Stream.of(new String[] {a,b,c});
// 람다 사용
Stream<Integer> oddStream = Stream.iterate(1, n->n+2);
Stream<Double> randomStream = Stream.generate(Math::random);
[ 중간 연산, 최종 연산 ]
연산결과가 Stream으로 반복적으로 적용가능한 중간연산과 연산결과가 Stream이 아닌 다른 타입인 경우 최종적으로 한번만 적용할 수 있어 최종연산이라고 함.
String [] arr = { "a1", "a2", "b1" };
Stream<String> stream = Stream.of(arr); // 문자열 배열이 소스인 스트림
Stream<String> filter = stream.filter(); // 걸러내는 함수로 중간연산에 해당
Stream<String> distinct = stream.distinct(); // 중복을 제거하는 함수로 중간연산에 해당
Stream<String> sorted = stream.sort(); // 정렬함수로 중간연산에 해당
Stream<String> limited = stream.limit(x); // x번째까지 자르는 함수로 중간연산에 해당
int total (다른 변수타입) = stream.count(); // 갯수 세기로 int타입 반환으로 최종연산에 해당
[ 중간연산 ]
- 스트림 자르기
- skip(x) : 앞에서 x번 건너뛰기
- limit(x) : x 이후로 요소 잘라내기
- 스트림 요소 걸러내기
- filter(조건) : 조건에 맞지 않는 요소 제거
- distinct() : stream 내 중복 제거.
- 스트림 정렬하기
- sorted() : 기본 정렬
- sorted(Comparator<>) : 지정된 Comparator로 정렬 역시 가능
- 스트림 요소 변환학
- map()
Stream<File> fileStream = Stream.of(new File("aaa.java"), new File("bbb.java"));
// Type 변환
Stream nameStream = fileStream.map(File::getName);
// example
fileStream.map(File.getName) // Stream<File> -> Stream<String>
.filter(s->s.indexof('.') != -1) // 확장자 없는 것 제외 Stream<String> -> Stream<String>
.map(s->s.substring(s.indexOf('.')+1) // 확장자 받기 Stream<String> -> Stream<String>
.map(String::toUpperCase) // 대문자 변환 Stream<String> -> Stream<String>
.distinct() // 중복제거 Stream<String> -> Stream<String>
.forEach(System.out::print); // 최종 연산
[ 최종 연산 ]
- 모든 요소에 지정된 작업 수행
- forEach() : 병렬스트림의 경우 순서 보장 안됨.
- forEachOredered() : 병렬스트림의 경우에도 순서가 보장.
- 스트림을 배열로 저장
- toArray() :
- Class [] className = classStream.toArray(); ==> 오류 발생
- Class [] className = classStream.toArray(Class[]::new);
- Object [] className = classStream.toArray();
- toArray() :
- 조건 검사
- allMatch() : 모든 요소가 조건을 만족시킨다면 true 리턴
- anyMatch() : 어떤 요소라도 조건을 만족시킨다면 true 리턴
- noneMatch() : 모든 요소가 조건을 만족시키지 못한다면 true리턴
- findFirst() : 조건을 만족하는 첫 번째 요소를 반환, sequential Stream
- findAny() : 조건을 만족하는 요소 중 하나 반환, parallelStream
- 통계 정보
- getCount() : Long Type
- getSum() : Integer Type
- getAverage() : OptionalDouble Type
- getMax() : OptinalInteger Type
- getMin() : OptinalInteger Type
- Collector 이용
- collect() : Collector를 매개변수로 하는 스트림의 최종 연산, Object collect (Collector collector)
- Collector : collect에 필요한 메소드를 정의해놓은 인터페이스, public interface Collector< 생략 >
- Collectors : 다양한 기능의 Collector를 구현한 클래스를 제공한다.
- 스트림을 컬렉션으로 변환
- toList() : Stream<T>를 List<T>으로 변환한다.
- toMap() : Stream<T>를 MAP<T, C>로 변환한다.
- toCollection() : Stream<T>를 ArrayList<T> 로 변환한다.
- 스트림을 컬렉션으로 변환
[ Optional ]
개발 중 가장 많이 발생하는 에러 중 하나로 NPE (NullPointException) 이 존재한다.
변수가 많으면 null 검사하는 코드의 복잡도가 올라간다.
JAVA8 이상으로 Optional<T> 클래스를 사용할 수 있게 되었고 NPE을 방지할 수 있도록 도우며 null이 올 수 있는 값을 감싸는 Wrapper Class로 참조하더라도 에러가 발생하지 않으며 클래스의 메소드를 사용할 수 있다.
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
private Optional() {
this.value = null;
}
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
}
Optional<String> optional = Optional.empty();
System.out.println(optional); // Optional.empty
System.out.println(optional.isPresent()); // false
// Optional의 value는 절대 null이 아니다.
Optional<String> optional = Optional.of("MyName");
// Optional의 value는 값이 있을 수도 있고 null 일 수도 있다.
Optional<String> optional = Optional.ofNullable(getName());
String name = optional.orElse("값이 없습니다."); // 값이 없다면 "값이 없습니다" 를 리턴
List<String> nameList = Optional.ofNullable(getNames())
.orElseGet(() -> new ArrayList<>());
[ orElse, orElseGet ]
Optional 클래스의 메소드에 정의되어 있듯이 orElse는 파라미터로 값을 전달받아 null 이라면 전달받은 값을 리턴하며 null 이 아니라면 orElse() 내용을 출력한다 하지만 orElseGet은 null 이 아니라면 내용을 출력하지 않는다.
public void findUserEmailOrElse() {
String userEmail = "Empty";
String result = Optional.ofNullable(userEmail)
.orElse(getUserEmail());
System.out.println(result);
// getUserEmail() Called
// Empty
}
public void findUserEmailOrElseGet() {
String userEmail = "Empty";
String result = Optional.ofNullable(userEmail)
.orElseGet(this::getUserEmail);
System.out.println(result);
// Empty
}
public void findUserEmailOrElseGet() {
String result = Optional.ofNullable(null)
.orElseGet(this::getUserEmail);
System.out.println(result);
// getUserEmail() Called
// mangkyu@tistory.com
}
private String getUserEmail() {
System.out.println("getUserEmail() Called");
return "mangkyu@tistory.com";
}
[ 참고자료 ]
[JAVA]람다와 스트림(Lambda & Stream)
1. 람다식(Lambda Expression) 1.1. 람다식이란? - 함수(메서드)를 간단한 식으로 표현하는 방법 - 익명 함수(이름이 없는 함수) - 함수와 메서드의 차이 - 근본적으로 동일. 함수는 일반적 용어. 메서
bombichun.tistory.com
[Java] Optional이란? Optional 개념 및 사용법 - (1/2)
이번에는 Java8부터 지원하는 Optional 클래스에 대해 알아보도록 하겠습니다. 1. Optional이란? Optional 개념 및 사용법 [ NPE(NullPointerException) 이란? ] 개발을 할 때 가장 많이 발생하는 예외 중 하나..
mangkyu.tistory.com
[JAVA] 람다식(Lambda)의 개념 및 사용법
람다함수란? 람다 함수는 프로그래밍 언어에서 사용되는 개념으로 익명 함수(Anonymous functions)를 지칭하는 용어입니다. 현재 사용되고 있는 람다의 근간은 수학과 기초 컴퓨터과학 분야에서의
khj93.tistory.com
'🍃 스프링' 카테고리의 다른 글
[SPRING] 남의 코드 이해하기 (1) | 2023.05.07 |
---|---|
[SPRING] Filter, Interceptor (0) | 2022.10.06 |
[SPRING] Dispatcher Servlet (0) | 2022.10.02 |
[SPRING] JPA, ORM (0) | 2022.09.27 |
[SPRING] Maven, Gradle (0) | 2022.09.24 |