17일차(애너테이션, 람다, 스트림)

Rina's·2023년 5월 2일

코드스테이츠

목록 보기
16/96
post-thumbnail

🍹애너테이션

컴파일이나 프로그램 실행시 정보 제공
@키워드를 붙여 사용
클래스, 인터페이스, 필드, 메서드 등에 사용
기본적으로 JDK가 제동하나 타 프로그램에서 제공하기도 한다

표준 애너테이션

JDK에 내장된 기본 애너테이션, 경고메세지를 주로 주는녀석

@Override
구현된 메서드와 같은이름의 상위 메서드가 없으면 컴파일 에러를 발생시킴

@Deprecated
기존 코드를 더이상 사용하지 않도록 권고, 사용 시 취소선과 함께 경고메세지를 출력
보통 호환성 문제로 삭제하지 못한 구 버전 코드를 위해 사용

@SuppressWarnings
컴파일 경고 메세지가 나타나지 않도록 함
경고 메제지를 예측하고 묵인하기 위해 사용
@SuppressWarnings("경고메세지") 형태로 지정해 사용(복수 지정 가능)
"all", "deprecation", "null".. etc

@FunctionalInterface
함수형 인터페이스 사용이 제대로 작성되었는지 검사

메타 애너테이션

타 애너테이션을 정의하는 애너테이션
이 중 직접 정의하여 사용하는 것을 사용자 정의 애너테이션이라 정의
애너테이션의 정의는 접근제어자 @interface 애너테이션명 {애너메이션 요소 선언();}으로 정의된다

@Target
애너테이션 적용 대상을 지정,
일반 애너테이션 정의부분에 @Target()으로 표시 됨

타겟 지정가능 열거형(ElementType)들
ANNOTATION_TYPE CONSTRUCTOR
FIELD LOCAL_VARIABLE METHOD PACKAGE
PARAMETER TYPE(cless, interface, enum)
TYPE_PARAMETER TYPE_USE(타입이 사용되는 모든 대상)

@Documented
애너테이션 정보가 javadoc으로 작성한 문서에 포함되도록 하는 설정
@Override과 @SuppressWarnings 외에는 기본 적용

@Inherited
하위클래스가 애너테이션도 함께 상속받도록 함

@Retention
애너테이션의 지속시간을 정의
SOURCE 소스 파일에 존재, 클래스파일에는 존재하지 않음
CLASS 클래스 파일에 존재, 실행 시에 사용 불가, 기본값
RUNTIME 클래스 파일에 존재, 실행 시에 사용가능

@Retention(RetentionPolicy.SOURCE)
소스 파일에 존재 컴파일러(클래스파일화)가 끝나면 사용x

@Repeatable
애너테이션을 여러 번 사용할 수 있게 함
@Repeatable(컨테이너 애너테이션명)

이를 위해 중복된 애너테이션을 하나로 묶는 컨테이너 애너테이션을 만들어야 함.

@Works({
    @Work("Design"),
    @Work("Development"),
    @Work("Testing")
})

🍸람다

람다식(Lambda Expression)

함수형 프로그래밍 기법을 지원하는 자바 문법
메서드를 하나의 식으로 표현

함수형 인터페이스

익명 객체는 익명클래스로 만들어진다

[익명 클래스]생성과 선언을 동시에 하여
하나의 객체만 생성하고 한번만 사용되는 일회용 클래스

new Object() {
	int sum(int num1, int num2) {
		return num1 + num1;
	}
}

익명 클래스는 [함수형 인터페이스]로 만들어진다

함수형 인터페이스는 단 하나의 추상메서드만 선언된다
[함수형 인터페이스] -> [익명클래스] -> [익명객체로 람다식 구현] (함수형 인터페이스의 구현)
함수형 인터페이스의 [추상메서드][매개변수와 반환타입]이 1:1로 일치할 때
람다식 생략이 가능해짐
@FunctionalInterface 애너테이션을 통해 함수형 인터페이스를 정의

반환타입, 이름을 생략(익명함수)
코드블록(){} 사이에 -> 삽입
실행문이 하나만 존재할때 { ;}생략 가능
return문만 있으면, 중괄호 {}와 return문 생략 가능
함수형 인터페이스매개변수 타입유추가능시 타입 생략가능

매개변수와 리턴값이 없을경우 () -> {}
매개변수가 있고 리턴값이 없을경우 (x) -> {}
매개변수와 리턴값이 있을 경우 (x) -> {return;}

기본제공 함수형 인터페이스를 확인해 보자

메서드 참조

람다식에서 불필요한 매개변수를 제거
1. 정적 메서드 참조 (클래스이름::메서드이름)
2. 인스턴스 메서드 참조 (참조 변수 :: 메서드)
3. 생성자 참조 (클래스 :: new)

🍦스트림

배열 및 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 하는 반복자
객체를 stream으로 생성하여 간결하고 직관적인 코드로 만들어 준다

명령형 프로그래밍 vs 선언형 프로그래밍(stream)

대표적인 특징

  • 3단계 파이프라인(생성, 중간 연산(가공), 최종 연산)
  • read-only(원본 데이터 유지)
  • onetime-only(스트림객체는 일회용)
  • 내부 반복자(처리코드 제공 - 모든데이터 처리 <-> 외부반복자(조건문, 반복문))

생성

1. 배열 스트림 생성 메서드
Array클래스와 Stream 인터페이스로 나뉜다
Arrays.stream(arr) Stream.of(arr)

Stream<String> stream = Arrays.stream(arr);
Stream<String> stream = Stream.of(arr);

이외 기본형 배열도 IntStream DoubleStream LongStream 로 형변환이 가능하다

IntStream intStream = Arrays.stream(intArr);

** Arrays클래스의 Stream(int[])는 Stream의 하위 인터페이스인 IntStream 타입으로 형변환 시키는 메서드이다

2. 컬렉션 스트림(List, Set)
Collection 클래스의 stream()를 사용하여 생성한다

 List<Integer> list = Arrays.asList(1, 2, 3);
 Stream<Integer> stream = list.stream();
 배열을 리스트화 하여 스트림

3. 임의의 수 스트림
Random 클래스의 메서드들
int() 범위 내에서 난수를 생성하여 IntStream으로 반환
이때 난수는 무한스트림, range()rangeClosed() 사용하여 범위지정 가능

IntStream ints = new Random().ints();

** 참고용

중간 연산자

  1. 필터링
    filter() 중복 제거
    distinct() 조건(람다식)에 맞는 데이터 추출

  2. 매핑
    map() 조건(람다식)에 맞는 필드 추출, 특정 형태로 변환
    flatMap() 중첩 구조를 제거

  3. 정렬
    sorted() 기본값은 오름차순, Comparator 인터페이스 내 메서드와 함께 사용

  4. 기타
    skip() 일부 요소들을 건너뜀
    limit() 일부를 자름
    peek() 요소들을 순회하며 특정 작업을 수행 최종 연산자인 forEach()와 달리 여러번 사용가능

최종 연산자

  1. 기본집계
    sum() count() average() max() min() findFirst() findAny()

  2. 매칭
    allMatch() 모든 요소가 조건을 만족하는지
    noneMatch 모든 요소가 조건을 불만족하는지
    anyMatch() 하나라도 조건을 만족하는 요소가 있는지

  3. 요소 소모
    reduce() 스트림의 요소를 줄여나가면서 연산을 수행하고 최종적인 결과를 반환
    forEach(요소 -> 요소.액션) 각 요소에 대해 주어진 동작을 수행

  4. 요소 수집
    collect() 스트림의 요소들을 List, Set, Map 등 다른 타입으로 수집하여 반환
    toArray()

갑자기 일일 공부량이 확 많아진 것 같은데 제 착각인가요??

최고 효율의 I/O를 위한 개발자들의 노력의 결과, 짜잔 람다식이 개발되었습니다
예? 이거 다 외워요..? 나중에 편할려면 지금 고생해야 하는거라고요?
'게을러 지고싶어 성실해진다'는 역설을 실현하는 개발자들이라니...

매서드 참조, 스트림부분 다시보기

profile
갭린이 리나

0개의 댓글