😂쇠사슬을 만들 때는...
어디선가 들은 얘기로는 쇠사슬 공정의 마지막은 '당겨보기'라고 했다. 꼭 전체 사슬을 당겨보는 검수를 한다는데, 각 고리에 대한 부하 테스트만 할 거라 생각했던 내게 묘한 깨달음을 준 이야기였다. 각 사슬이 아무리 압력에 강해도 사슬 간 연결부분이 약하면 제 목적을 달성하지 못하는 것이다. 하나하나는 안다고 생각해도 슬쩍 넘어갔던 부분들이 모여 나오면 당황하게 된다.. 그러니까 뿌셔보자!
🚀Stream method 목차 정리
Stream 생성
- 컬렉션에서 Stream<T> intStream = list.stream()
- 배열에서
- 무한 스트림 -람다식
- 파일 Files.list(디렉토리)
- 빈 스트림
- 두 스트림 연결 Stream.concat(strs1, strs2)
Stream 중간연산
- 스트림 자르기
- 스트림 요소 걸러내기
- 정렬하기
- 변환하기 map()
저장된 값 중에서 원하는 필드만 뽑아내기
특정 형태로 변환하기
Stream<R> map(<super T,? extends R> mapper)
Stream<File> fileStream = Stream.of(new File("EX1.java"), new File("Ex1"), new File("Ex1.bak");
Stream<String> filenameStream =fileStream.map(File::getName);
filenameStream.forEach(System.out::printLn);
- 조회하기
- T[ ]배열 요소를 T로
Stream 최종연산
Stream의 요소합 등 단일값 or 스트림 요소가 담긴 배열 or Collection
- 스트림 요소 출력하기
void forEach(System.out::println)
- 조건 검사
- 통계
- 리듀싱
🚀Lambda 생략 순서 요약
1.기본방식
2.실행문이 하나만 존재할 때
3.매개변수 타입을 쉽게 유추할 수 있는 경우
코드예제
max() 람다식 변환
반환타입, 이름 제거(익명함수이므로)
int max(int a, int b) {
return a>b ? a:b;
}
매개변수 선언부→바디
int max(int a, int b) ->{
return a>b ? a:b;
}
반환값이 있다면 기존의 return문을 expression으로 대체
- return을 생략할 때는 ⭐⭐개행 ‘;’을 붙이지 않는다
- return을 붙이고 싶다면 무조건 중괄호가 있어야 한다
int max(int a, int b) -> {a>b ? a:b}
람다식에 선언된 매개변수 타입은 보통 추론 가능→생략
(a, b) -> {a>b ? a:b}
괄호, 중괄호 생략 case
- 선언된 매개변수가 하나→괄호 생략
a -> a>b ? a:b;//ok
(int a) -> a>b ? a:b//ok
- 메서드 바디 문장이 하나→ 중괄호 생략, ‘;’생략
함수형 인터페이스
람다는 메서드와 동일시했지만, 사실 익명 클래스임
익명클래스
객체의 선언과 생성을 동시에 하며
오직 하나의 객체를 생성해 단 한 번만 사용하는 일회용 클래스
즉, 람다식은 아래와 같다
(int a, int b) -> a>b?a:b
//라는 람다식은 아래와 완전히 같다
new Object(){
int max(int a, int b){
return a>b ? a: b
}
}
그러나 이 익명객체의 메서드는 어떻게 쓸 수 있을 것인가?
참조변수가 있어야 메서드를 호출할 수 있기 때문에
타입 f =~방식일 텐데, 람다식과 동일한 메서드가 정의되어 있어야 하겠다.
그렇기 때문에 인터페이스를 구현한 익명 클래스 객체로서 람다를 만들고, 그런 인터페이스를 함수형 인터페이스라고 부르기로 했다
public class LamdaExample1 {
public static void main(String[] args) {
Object obj = new Object() {
int sum(int num1, int num2) {
return num1 + num1;
}
};
// 람다식 Object obj = (num1, num2) -> num1 + num2 로 대체 가능
}
원래의 sum이라는 메서드는 온데간데 없이 사라져버렸음
그렇기 때문에 인터페이스를 1:1 매치하게 되는 것
완전히 같은 메서드가 있어야만 작동할 수 있기 떄문에
앞서 학습한 FunctionalInterface 어노태이션을 통해 확인하면서 작성하는 걸 추천
public class LamdaExample1 {
public static void main(String[] args) {
/* Object obj = new Object() {
int sum(int num1, int num2) {
return num1 + num1;
}
};
*/
ExampleFunction exampleFunction = (num1, num2) -> num1 + num2
System.out.println(exampleFunction.sum(10,15))
}
@FunctionalInterface // 컴파일러가 인터페이스가 바르게 정의되었는 지 확인할 수 있도록
interface ExampleFunction {
public abstract int sum(int num1, int num2);
}
// 출력값
25
즉 람다를 쓰고 싶으면, 무조건 인터페이스를 만들어준 뒤, 인터페이스의 인스턴스를 생성해 작성한다.
매개변수와 리턴값이 없는 람다식
@FunctionalInterface
public interface MyFunctionalInterface {
public void accept();
}
인 경우 람다식은
MyFunctionalInterface example = () -> { ... };
// example.accept();
바로 accept를 호출하게 된다
public class MyFunctionalInterfaceExample {
public static void main(String[] args) throws Exception {
MyFunctionalInterface example;
example = () -> {
String str = "첫 번째 메서드 호출!";
System.out.println(str);
};
example.accept();
example = () -> System.out.println("두 번째 메서드 호출!");
//실행문이 하나라면 중괄호 { }는 생략 가능
example.accept();
}
}
// 출력값
첫 번째 메서드 호출!
두 번째 메서드 호출!
이렇게 따로 클래스 작성 없이도 가능하다는 큰 장점이 있다
📒프로젝트에서 만났던 Stream, Lambda 코드모음
1) Stream.map+ lamda 메서드 참조
List<Coffee> orderedCoffees = order.getOrderCoffeeList().stream()
.map(orderCoffee::getCoffee)
.collect(Collectors.toList());
order.getOrderCoffeeList().stream()
- orderCoffeeList를 stream으로 변환
→Stream<OrderCoffee> orderedCoffeesStream
.map(orderedCoffee :: getCoffee)
함수형 인터페이스를 인자로 받기 때문에 메서드 레퍼런스가 들어갔다
(orderCoffee::getCoffee)
- orderCoffee는 OrderCoffee 타입 스트림의 객체 하나하나를 의미
- 그중에서 일부 필드인 coffee를 받기 위해 쓰는 메서드인 getCoffee
- 즉, 각 객체에서 coffee 필드만 뽑아와라
.collect(Collection.toList())
collect()로 list 변환
2) Stream+Lambda
.filter(n -> n.startsWith(lastName))
이 람다를 풀어쓰면 어떻게 될까?
생략된 것을 찾아보면
- 메서드명, 반환타입
- 매개변수 소괄호
- 메서드바디 중괄호
람다 문법을 이해했으니 다시 적어보면
stream()
.filter(자료형 n){
return n.startsWith(lastName)
}
3) Lambda를 파라미터로 넣기
assertThrows(BusinessLogicException.class, () -> memberService.createMember(member));
실행이 되면 exception이 날 거고, 그 익셉션이 비즈니스 익셉션일 것이라는 뜻
매개변수 , 리턴값이 없고 실행문이 한 문장이어서 생략된 케이스다.
'Web > Java' 카테고리의 다른 글
JSON ,ObjectMapper, 직렬화(serialization)역직렬화(deserialization), transferable condition (0) | 2022.07.23 |
---|---|
⭐추상화(1) 상속vs추상화, abstract제어자, 추상클래스, 추상메서드, final 키워드 (0) | 2022.07.18 |