익명 클래스보다는 람다를 사용하라
타입을 명시해야 코드가 더 명확 할 때만을 제외하고는 람다의 모든 매개변수 타입은 생략해야한다.
이후 컴파일러가 "타입을 알 수 없다" 라는 오류를 낼 경우에만 해당 타입을 명시하면 된다.
람다의 단점은 이름이 없으며 문서화를 하지 못하기에 코드 자체로 동작이 명확히 설명되지 않거나 코드줄 수가 많아 지는 경우에는 람다를 사용하지 말아야 한다. (세줄이 넘어가면 사용하지 않는 것이 좋다)
람다는 자신을 참조 할 수 없기때문에 람다에서 this 키워드는 바깥 인스턴스를 가리키며, 익명에서의 this는 익명 클래스의 인스턴스 this를 가르킨다.
익명 클래스는 함수형 인터페이스가 아닌 타입의 인스턴스를 만들때 만 사용하는 것이 좋다.
람다보다는 메서드 참조를 사용하라
메서드 참조의 유형은 5가지다.
1. 정적 메서드를 가리키는 메서드 참조
인스턴스 메서드를 참조하는 유형 2가지
2. 수신 객체를 특정하는 한정적 인스턴스 메서드 참조
3. 수신객체를 특정하지 않는 비한정적 인스턴스 메서드 참조
한정적 참조는 근본적으로 저적 참조와 비슷하기에 함수 객체가 받는 인수와 참조되는 메서드가 받는 인수가 똑같다.
비한정적 참조에서는 함수 객체를 적용하는 시점에 수신 객체를 알려준다. 이를 위해 수신 객체는 전달용 매개변수가 매개변수 목록의 첫번째로 추가 되며 그 뒤로는 참조 메서드 선언에 정의된 매개변수들이 따른다.
4. 클래스 생성자
5. 배열 생성자
메서드 참조가 짧고 명확하다면 사용하고 그 외의 경우에는 람다를 사용하는 것이 좋다.
표준 함수형 인터페이스를 사용하라
객체지향 5대 원칙
분리 - 불변, 가변 별로
- 관심사 (SOC)별로
- 중복제거
- 가변 불변을 분리하는 패턴
- 불변 조상, 가변 자손
필요한 용도에 맞는 것이 있다면 직접 구현하는것 보다는 표준 함수형 인터페이스를 활용해야 한다.
표준 함수형 인터페이스 대부분은 기본 타입만을 지원하지만 기본 함수형 인터페이스에 박싱된 기본타입을 사용하는 것은 계산이 많은 경우 성능이 느려지도록 한다.
대표적인 Comparator<T> 인터페이스 특성 3가지중 하나 이상을 만족한다면 전용 함수형 인터페이스를 고려하는 것이 좋다.
1. 자주쓰이며, 이름 자체가 용도를 명확하게 설명해준다.
2. 반드시 따라야하는 규약이 있다.
3. 유용한 디폴트 메서드를 제공할 수 있다.
전용함수형 인터페이스 작성시 주의점
@FunctionalInterface 애너테이션을 사용하는 이유는 프로그래머의 의도를 명시하는 것으로 첫번째, 해당 클래스의 코드나 설명문서를 그 인터페이스가 람다용으로 설계된것임을 알려준다. 둘째, 해당 인터페이스가 추상 메서드를 오직하나만 가지고 있어야 컴파일 되게 해준다. 세번째, 유지보수 과정에서 메서드를 추가하지 못하도록 막아준다.
스트림은 주의해서사용하라
스트림의 부작용 - 함수의 작업이 끝나거나 이전으로 되돌렸을 때, 상태가 달라지는 현상이 생기기도 한다.
1. 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 뜻한다.
2. 스트림 파이프 라인은 이 원소들로 수행하는 연산 단계를 표현하는 개념이다.
스트림 파이프 라인은 지연 평가 되며, 평가는 종단 연산이 호출될때 이뤄지기에 종단 연산을 빼먹는 일이 발생해서는 안된다.
스트림을 과용하면 프로그램의 가독성이 떨어지거나 유지보수가 어려워진다.
상황에 따라 알맞게 사용하는 것이 좋으며 스트림과 반복 모두 사용해보고 나은 쪽을 선택하는 것이 좋다.
스트림에서는 부작용 없는 함수를 사용하라
스트림 파이프라인 프로그래밍의 핵심은 부작용 없는 함수 객체에 있으며, 스트림뿐 아니라 스트림 관련 객체에 건네지는 모든 함수 객체가 부작용이 없어야한다. 종단 연산 중 forEach는 스트림이 수행한 결과를 보고 할 때만 이용해야한다.
스트림을 사용하기 위해 사용하는 Collector에는 toList, toSet, toMap, groupingBy, joining 이있다.
변환 타입으로는 스트림보다 컬렉션이 낫다
원소 시퀀스를 반환하는 공개 API의 반환 타입에는 Collection이나 그 하위 타입을 쓰는 것이 일반적으로 최선이다. 또한 단지 컬렉션을 반환한다는 이유로 큰 시퀀스를 메모리에 올려서는 안된다.
스트림 병렬화는 주의해서 적용하라
병렬화 시에는 대부분 스트림의 소스가 ArrayList, HashMap, HashSet, ConcurrentHashMap의 인스턴스거나 배열, int 범위, long 범위일 때 병렬화의 효과가 가장 좋다.
만약 스트림을 잘못 병렬화하게 된다면 응답 불가이거나 성능이 나빠지는 등의 동작이 발생 할 수 있다.
'IT > Java' 카테고리의 다른 글
정규식 추출 (0) | 2020.03.17 |
---|---|
이펙티브 자바 8장 - 메서드 (0) | 2020.01.06 |
이펙티브 자바 6장 - enum 2 (0) | 2020.01.03 |
이펙티브 자바 6장 - enum (0) | 2019.12.12 |
이펙티브 자바 5장 - 제네릭 2 (0) | 2019.12.05 |
댓글